type conversion
I want to do the following
expr.Eval("value + 2", map[string]interface{"value": "1"})
But value is a string. Casting func?
expr.Eval("int(value) + 2", map[string]interface{"value": "1"})
You can add helper. Like this: func Int(s string) { ... }
It would be nice to have build in support.
I was thinking about it too. But still can’t find good solution what will simple enough to explain to not programmer users of expr.
could it be optional? E.g expr.TypeConvertors()
In Golang, I think there are only so many conversions you can do. One challenge is if the casting was not sensible due to loss of accuracy (e.g. to float64) or just invalid (the string "foo" to int)
Yes, we need to find reasonable behaviour in case of loss of accuracy , or other errors.
var castErr error // stash any casting error here
replaceMap["int"] = func(s string) int {
v, err := strconv.Atoi(s)
if err != nil {
castErr = fmt.Errorf("failed to cast %q to int: %w", s, err)
}
return v
}
replaceMap["array"] = func(s string) []interface{} {
array := make([]interface{}, 0)
if err := json.Unmarshal([]byte(s), &array); err != nil {
castErr = fmt.Errorf("failed to cast %q to array: %w", s, err)
}
return array
}
result, err := expr.Eval(expression, bellows.Expand(replaceMap))
if err == nil {
err = castErr
}
if err != nil {
return nil, fmt.Errorf("failed to evaluate expression %q: %w", expression, err)
}
Array cast looks more like Json.parse.
One solution to this might be for users to add the Sprig functions. They have a big library and it seems to work nicely:
http://masterminds.github.io/sprig/conversion.html
There are security issues with Sprig methinks, need to understand what sub-set of commands are safe.
I think adding some basic casting based on https://github.com/spf13/cast would be useful.
toFloat, toString, ...
Looking forward to this enhancement. It would be a massive life-saving feature by avoiding putting custom patch functions in every time into map.
I was thinking about this, maybe you can introduce a new Node type: ConversionNode with a new OpCode: OpConversion. (IDK there is already a OpCast opcode, it seems to do something for the config.Expect stuff) - don't know much about the internals, just using the keywords as a placeholder.
But still can’t find good solution what will simple enough - @antonmedv
What about:
-
float64(Foo.Bar) -
int("Baz.Qux") -
string(Quux)
If conversion fails, the Compile() func should return an error.
Yeah, I’m working on adding this feature)
Added int() and float().