fix(variform): allow numbers to be numbers

This commit is contained in:
zmstone 2024-04-10 10:19:38 +02:00
parent 2fea651d1d
commit e6330dddec
4 changed files with 46 additions and 8 deletions

View File

@ -83,8 +83,10 @@ eval_as_string(Expr, Bindings, _Opts) ->
eval({str, Str}, _Bindings) -> eval({str, Str}, _Bindings) ->
str(Str); str(Str);
eval({num, Num}, _Bindings) -> eval({integer, Num}, _Bindings) ->
str(Num); Num;
eval({float, Num}, _Bindings) ->
Num;
eval({array, Args}, Bindings) -> eval({array, Args}, Bindings) ->
eval(Args, Bindings); eval(Args, Bindings);
eval({call, FuncNameStr, Args}, Bindings) -> eval({call, FuncNameStr, Args}, Bindings) ->
@ -150,7 +152,7 @@ resolve_func_name(FuncNameStr) ->
resolve_var_value(VarName, Bindings) -> resolve_var_value(VarName, Bindings) ->
case emqx_template:lookup_var(split(VarName), Bindings) of case emqx_template:lookup_var(split(VarName), Bindings) of
{ok, Value} -> {ok, Value} ->
str(Value); Value;
{error, _Reason} -> {error, _Reason} ->
<<>> <<>>
end. end.

View File

@ -7,7 +7,8 @@ Nonterminals
Terminals Terminals
identifier identifier
number integer
float
string string
'(' ')' '(' ')'
',' '[' ']'. ',' '[' ']'.
@ -34,7 +35,8 @@ args -> args ',' arg : '$1' ++ ['$3'].
%% Arguments can be expressions, arrays, numbers, or strings %% Arguments can be expressions, arrays, numbers, or strings
arg -> expr : '$1'. arg -> expr : '$1'.
arg -> array : '$1'. arg -> array : '$1'.
arg -> number : {num, element(3, '$1')}. arg -> integer: {integer, element(3, '$1')}.
arg -> float: {float, element(3, '$1')}.
arg -> string : {str, element(3, '$1')}. arg -> string : {str, element(3, '$1')}.
Erlang code. Erlang code.

View File

@ -3,7 +3,8 @@ Definitions.
IDENTIFIER = [a-zA-Z][a-zA-Z0-9_.]* IDENTIFIER = [a-zA-Z][a-zA-Z0-9_.]*
SQ_STRING = \'[^\']*\' SQ_STRING = \'[^\']*\'
DQ_STRING = \"[^\"]*\" DQ_STRING = \"[^\"]*\"
NUMBER = [+-]?(\\d+\\.\\d+|[0-9]+) INTEGER = [+-]?[0-9]+
FLOAT = [+-]?\\d+\\.\\d+
LPAREN = \( LPAREN = \(
RPAREN = \) RPAREN = \)
LBRACKET = \[ LBRACKET = \[
@ -12,12 +13,12 @@ COMMA = ,
WHITESPACE = [\s\t\n]+ WHITESPACE = [\s\t\n]+
Rules. Rules.
%% Match function names, variable names (with ${}), strings, numbers, and structural characters
{WHITESPACE} : skip_token. {WHITESPACE} : skip_token.
{IDENTIFIER} : {token, {identifier, TokenLine, TokenChars}}. {IDENTIFIER} : {token, {identifier, TokenLine, TokenChars}}.
{SQ_STRING} : {token, {string, TokenLine, unquote(TokenChars, $')}}. {SQ_STRING} : {token, {string, TokenLine, unquote(TokenChars, $')}}.
{DQ_STRING} : {token, {string, TokenLine, unquote(TokenChars, $")}}. {DQ_STRING} : {token, {string, TokenLine, unquote(TokenChars, $")}}.
{NUMBER} : {token, {number, TokenLine, TokenChars}}. {INTEGER} : {token, {integer, TokenLine, list_to_integer(TokenChars)}}.
{FLOAT} : {token, {float, TokenLine, list_to_float(TokenChars)}}.
{LPAREN} : {token, {'(', TokenLine}}. {LPAREN} : {token, {'(', TokenLine}}.
{RPAREN} : {token, {')', TokenLine}}. {RPAREN} : {token, {')', TokenLine}}.
{LBRACKET} : {token, {'[', TokenLine}}. {LBRACKET} : {token, {'[', TokenLine}}.

View File

@ -39,11 +39,44 @@ redner_test_() ->
{"out of range nth index", fun() -> {"out of range nth index", fun() ->
?assertEqual({ok, <<>>}, render("nth(2, tokens(var, ','))", #{var => <<"a">>})) ?assertEqual({ok, <<>>}, render("nth(2, tokens(var, ','))", #{var => <<"a">>}))
end}, end},
{"string for nth index", fun() ->
?assertEqual({ok, <<"a">>}, render("nth('1', tokens(var, ','))", #{var => <<"a">>}))
end},
{"not a index number for nth", fun() -> {"not a index number for nth", fun() ->
?assertMatch( ?assertMatch(
{error, #{reason := invalid_argument, func := nth, index := <<"notnum">>}}, {error, #{reason := invalid_argument, func := nth, index := <<"notnum">>}},
render("nth('notnum', tokens(var, ','))", #{var => <<"a">>}) render("nth('notnum', tokens(var, ','))", #{var => <<"a">>})
) )
end},
{"substr", fun() ->
?assertMatch(
{ok, <<"b">>},
render("substr(var,1)", #{var => <<"ab">>})
)
end},
{"result in integer", fun() ->
?assertMatch(
{ok, <<"2">>},
render("strlen(var)", #{var => <<"ab">>})
)
end},
{"result in float", fun() ->
?assertMatch(
{ok, <<"2.2">>},
render("var", #{var => 2.2})
)
end},
{"concat a number", fun() ->
?assertMatch(
{ok, <<"2.2">>},
render("concat(strlen(var),'.2')", #{var => <<"xy">>})
)
end},
{"var is an array", fun() ->
?assertMatch(
{ok, <<"y">>},
render("nth(2,var)", #{var => [<<"x">>, <<"y">>]})
)
end} end}
]. ].