diff --git a/apps/emqx_message_transformation/src/emqx_message_transformation.erl b/apps/emqx_message_transformation/src/emqx_message_transformation.erl index f39ddf22f..84af327f6 100644 --- a/apps/emqx_message_transformation/src/emqx_message_transformation.erl +++ b/apps/emqx_message_transformation/src/emqx_message_transformation.erl @@ -160,7 +160,14 @@ eval_operation(Operation, Transformation, Context) -> -spec eval_variform([binary(), ...], _, eval_context()) -> {ok, rendered_value()} | {error, term()}. eval_variform(K, V, Context) -> - case emqx_variform:render(V, Context) of + Opts = + case K of + [<<"payload">> | _] -> + #{eval_as_string => false}; + _ -> + #{} + end, + case emqx_variform:render(V, Context, Opts) of {error, Reason} -> {error, Reason}; {ok, Rendered} -> diff --git a/apps/emqx_message_transformation/src/emqx_message_transformation_bif.erl b/apps/emqx_message_transformation/src/emqx_message_transformation_bif.erl index 0eaf46578..96085c341 100644 --- a/apps/emqx_message_transformation/src/emqx_message_transformation_bif.erl +++ b/apps/emqx_message_transformation/src/emqx_message_transformation_bif.erl @@ -28,7 +28,7 @@ json_encode(X) -> json_decode(JSON) -> case emqx_utils_json:safe_decode(JSON, [return_maps]) of {ok, X} -> - emqx_variform:skip_stringification(X); + X; {error, Reason} -> throw(#{reason => json_decode_failure, detail => Reason}) end. diff --git a/apps/emqx_utils/src/emqx_variform.erl b/apps/emqx_utils/src/emqx_variform.erl index e92be06dd..7a0bc8118 100644 --- a/apps/emqx_utils/src/emqx_variform.erl +++ b/apps/emqx_utils/src/emqx_variform.erl @@ -31,7 +31,6 @@ -export([render/2, render/3]). -export([compile/1, decompile/1]). --export([skip_stringification/1]). -export_type([compiled/0]). @@ -44,7 +43,6 @@ ). -define(IS_EMPTY(X), (X =:= <<>> orelse X =:= "" orelse X =:= undefined)). --define(SKIP_STRINGIFICATION, {?MODULE, '__skip_stringification__'}). %% @doc Render a variform expression with bindings. %% A variform expression is a template string which supports variable substitution @@ -71,7 +69,7 @@ render(Expression, Bindings) -> render(Expression, Bindings, #{}). render(#{form := Form}, Bindings, Opts) -> - eval_as_string(Form, Bindings, Opts); + eval_render(Form, Bindings, Opts); render(Expression, Bindings, Opts) -> case compile(Expression) of {ok, Compiled} -> @@ -80,9 +78,16 @@ render(Expression, Bindings, Opts) -> {error, Reason} end. -eval_as_string(Expr, Bindings, _Opts) -> +eval_render(Expr, Bindings, Opts) -> + EvalAsStr = maps:get(eval_as_string, Opts, true), try - {ok, return_str(eval(Expr, Bindings, #{}))} + Result = eval(Expr, Bindings, #{}), + case EvalAsStr of + true -> + {ok, return_str(Result)}; + false -> + {ok, Result} + end catch throw:Reason -> {error, Reason}; @@ -95,9 +100,6 @@ return_str(Str) when is_binary(Str) -> Str; return_str(Num) when is_integer(Num) -> integer_to_binary(Num); return_str(Num) when is_float(Num) -> float_to_binary(Num, [{decimals, 10}, compact]); return_str(Atom) when is_atom(Atom) -> atom_to_binary(Atom, utf8); -%% For usage by other modules (e.g.: message transformation) -return_str({?SKIP_STRINGIFICATION, X}) -> - X; return_str(Other) -> throw(#{ reason => bad_return, @@ -105,9 +107,6 @@ return_str(Other) -> got => Other }). -skip_stringification(X) -> - {?SKIP_STRINGIFICATION, X}. - %% @doc Compile varifom expression. -spec compile(string() | binary() | compiled()) -> {ok, compiled()} | {error, any()}. compile(#{form := _} = Compiled) ->