func-string.go: added three new functions (splitStr, startsWithStr, endsWithString) to the 'string' builtin module

This commit is contained in:
Celestino Amoroso 2024-05-06 15:29:13 +02:00
parent a9d6a82011
commit 5378952394

View File

@ -5,6 +5,7 @@
package expr
import (
"fmt"
"io"
"strings"
)
@ -102,13 +103,105 @@ func trimStrFunc(ctx ExprContext, name string, args []any) (result any, err erro
return
}
func startsWithStrFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var source string
var ok bool
result = false
if len(args) < 1 {
return result, errMissingRequiredParameter(name, paramSource)
}
if source, ok = args[0].(string); !ok {
return result, errWrongParamType(name, paramSource, typeString, args[0])
}
for i, targetSpec := range args[1:] {
if target, ok := targetSpec.(string); ok {
if strings.HasPrefix(source, target) {
result = true
break
}
} else {
err = fmt.Errorf("target item nr %d is %T, expected string", i+1, targetSpec)
break
}
}
return
}
func endsWithStrFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var source string
var ok bool
result = false
if len(args) < 1 {
return result, errMissingRequiredParameter(name, paramSource)
}
if source, ok = args[0].(string); !ok {
return result, errWrongParamType(name, paramSource, typeString, args[0])
}
for i, targetSpec := range args[1:] {
if target, ok := targetSpec.(string); ok {
if strings.HasSuffix(source, target) {
result = true
break
}
} else {
err = fmt.Errorf("target item nr %d is %T, expected string", i+1, targetSpec)
break
}
}
return
}
func splitStrFunc(ctx ExprContext, name string, args []any) (result any, err error) {
var source, sep string
var count int = -1
var parts []string
var ok bool
if len(args) < 1 {
return result, errMissingRequiredParameter(name, paramSource)
}
if source, ok = args[0].(string); !ok {
return result, errWrongParamType(name, paramSource, typeString, args[0])
}
if len(args) >= 2 {
if sep, ok = args[1].(string); !ok {
return nil, fmt.Errorf("separator param must be string, got %T (%v)", args[1], args[1])
}
if len(args) >= 3 {
if count64, ok := args[2].(int64); ok { // TODO replace type assertion with toInt()
count = int(count64)
} else {
return nil, fmt.Errorf("part count must be integer, got %T (%v)", args[2], args[2])
}
}
}
if count > 0 {
parts = strings.SplitN(source, sep, count)
} else if count < 0 {
parts = strings.Split(source, sep)
} else {
parts = []string{}
}
list := make(ListType, len(parts))
for i, part := range parts {
list[i] = part
}
result = &list
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("splitStr", &simpleFunctor{f: splitStrFunc}, 2, -1)
ctx.RegisterFunc("trimStr", &simpleFunctor{f: trimStrFunc}, 1, -1)
ctx.RegisterFunc("startsWithStr", &simpleFunctor{f: startsWithStrFunc}, 2, -1)
ctx.RegisterFunc("endsWithStr", &simpleFunctor{f: endsWithStrFunc}, 2, -1)
}
// Register the import function in the import-register.