diff --git a/func-string.go b/func-string.go new file mode 100644 index 0000000..45291d0 --- /dev/null +++ b/func-string.go @@ -0,0 +1,118 @@ +// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com). +// All rights reserved. + +// func-string.go +package expr + +import ( + "io" + "strings" +) + +// --- Start of function definitions +func doJoinStr(funcName string, sep string, it Iterator) (result any, err error) { + var sb strings.Builder + var v any + for v, err = it.Next(); err == nil; v, err = it.Next() { + if it.Index() > 0 { + sb.WriteString(sep) + } + if s, ok := v.(string); ok { + sb.WriteString(s) + } else { + err = errExpectedGot(funcName, typeString, v) + return + } + } + if err == nil || err == io.EOF { + err = nil + result = sb.String() + } + return +} + +func joinStrFunc(ctx ExprContext, name string, args []any) (result any, err error) { + if len(args) < 1 { + return nil, errMissingRequiredParameter(name, paramSeparator) + } + if sep, ok := args[0].(string); ok { + if len(args) == 1 { + result = "" + } else if len(args) == 2 { + if ls, ok := args[1].([]any); ok { + result, err = doJoinStr(name, sep, NewFlatArrayIterator(ls)) + } else if it, ok := args[1].(Iterator); ok { + result, err = doJoinStr(name, sep, it) + } else { + err = errInvalidParameterValue(name, paramParts, args[1]) + } + } else { + result, err = doJoinStr(name, sep, NewFlatArrayIterator(args[1:])) + } + } else { + err = errWrongParamType(name, paramSeparator, typeString, args[0]) + } + return +} + +func subStrFunc(ctx ExprContext, name string, args []any) (result any, err error) { + var start = 0 + var count = -1 + var source string + var ok bool + + if len(args) < 1 { + return nil, errMissingRequiredParameter(name, paramSource) + } + if source, ok = args[0].(string); !ok { + return nil, errWrongParamType(name, paramSource, typeString, args[0]) + } + if len(args) > 1 { + if start, err = toInt(args[1], name+"()"); err != nil { + return + } + if len(args) > 2 { + if count, err = toInt(args[2], name+"()"); err != nil { + return + } + } + if start < 0 { + start = len(source) + start + } + } + if count < 0 { + count = len(source) - start + } + end := min(start+count, len(source)) + result = source[start:end] + return +} + +func trimStrFunc(ctx ExprContext, name string, args []any) (result any, err error) { + var source string + var ok bool + + if len(args) < 1 { + return nil, errMissingRequiredParameter(name, paramSource) + } + if source, ok = args[0].(string); !ok { + return nil, errWrongParamType(name, paramSource, typeString, args[0]) + } + result = strings.TrimSpace(source) + return +} + +// --- End of function definitions + +// Import above functions in the context +func ImportStringFuncs(ctx ExprContext) { + ctx.RegisterFunc("joinStr", &simpleFunctor{f: joinStrFunc}, 1, -1) + ctx.RegisterFunc("subStr", &simpleFunctor{f: subStrFunc}, 1, -1) + ctx.RegisterFunc("trimStr", &simpleFunctor{f: trimStrFunc}, 1, -1) +} + +// Register the import function in the import-register. +// That will allow to import all function of this module by the "builtin" operator." +func init() { + registerImport("string", ImportStringFuncs, "string utilities") +}