Current section
Files
Jump to
Current section
Files
src/serializer.erl
-module(serializer).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([get_json_serializer_str/1, from/1]).
-spec glance_t_to_codegen_t(glance:type()) -> internal@codegen@types:gleam_type().
glance_t_to_codegen_t(X) ->
case X of
{named_type, Name, _, Parameters} ->
case Name of
<<"List"/utf8>> ->
_assert_subject = gleam@list:at(Parameters, 0),
{ok, T0} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"serializer"/utf8>>,
function => <<"glance_t_to_codegen_t"/utf8>>,
line => 19})
end,
{list_type, glance_t_to_codegen_t(T0)};
<<"Option"/utf8>> ->
_assert_subject@1 = gleam@list:at(Parameters, 0),
{ok, T0@1} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"serializer"/utf8>>,
function => <<"glance_t_to_codegen_t"/utf8>>,
line => 25})
end,
internal@codegen@types:option(glance_t_to_codegen_t(T0@1));
<<"Result"/utf8>> ->
erlang:error(#{gleam_error => panic,
message => <<"Result is unimplemented! serde-style tagging support needed https://serde.rs/enum-representations.html"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"glance_t_to_codegen_t"/utf8>>,
line => 31});
_ ->
{anonymous_type, Name}
end;
{tuple_type, Elements} ->
{tuple_type, gleam@list:map(Elements, fun glance_t_to_codegen_t/1)};
{function_type, _, _} ->
erlang:error(#{gleam_error => panic,
message => <<"cannot serialize entities with functions"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"glance_t_to_codegen_t"/utf8>>,
line => 41});
{variable_type, _} ->
erlang:error(#{gleam_error => panic,
message => <<"unimplemented! VariableType"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"glance_t_to_codegen_t"/utf8>>,
line => 46})
end.
-spec get_json_serializer_str(internal@codegen@types:gleam_type()) -> binary().
get_json_serializer_str(Ct) ->
case Ct of
{anonymous_type, Name} ->
<<"json."/utf8, (gleam@string:lowercase(Name))/binary>>;
{tuple_type, _} ->
<<"json.preprocessed_array"/utf8>>;
{list_type, _} ->
<<"json.array"/utf8>>;
{variant_dep_type, Name@1, _, _} ->
case Name@1 of
<<"Option"/utf8>> ->
<<"json.nullable"/utf8>>;
_ ->
<<(erlang:error(#{gleam_error => panic,
message => <<"VariantDefType not supported: "/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"get_json_serializer_str"/utf8>>,
line => 64}))/binary, Name@1/binary>>
end;
_ ->
erlang:error(#{gleam_error => todo,
message => <<"This has not yet been implemented"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"get_json_serializer_str"/utf8>>,
line => 70})
end.
-spec codegen_t_to_codegen_json_t(internal@codegen@types:gleam_type(), binary()) -> internal@codegen@statements:gleam_statement().
codegen_t_to_codegen_json_t(Ct, Field_name) ->
Json_call_fn_str = get_json_serializer_str(Ct),
Field_name_var = {var_primitive, <<"t."/utf8, Field_name/binary>>},
case Ct of
{anonymous_type, _} ->
internal@codegen@statements:call(Json_call_fn_str, [Field_name_var]);
{tuple_type, Els} ->
internal@codegen@statements:call(
Json_call_fn_str,
[internal@codegen@statements:list(
gleam@list:index_map(
Els,
fun(El, I) ->
codegen_t_to_codegen_json_t(
El,
<<<<Field_name/binary, "."/utf8>>/binary,
(gleam@int:to_string(I))/binary>>
)
end
)
)]
);
{list_type, Inner} ->
internal@codegen@statements:call(
Json_call_fn_str,
[Field_name_var,
{var_primitive, get_json_serializer_str(Inner)}]
);
{variant_dep_type, _, Dep_types, _} ->
internal@codegen@statements:call(
Json_call_fn_str,
[Field_name_var |
gleam@list:map(
Dep_types,
fun(Inner@1) ->
{var_primitive, get_json_serializer_str(Inner@1)}
end
)]
);
_ ->
erlang:error(#{gleam_error => todo,
message => <<"This has not yet been implemented"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"codegen_t_to_codegen_json_t"/utf8>>,
line => 109})
end.
-spec serializer_of_t(glance:type(), binary()) -> internal@codegen@statements:gleam_statement().
serializer_of_t(X, Field_name) ->
Ct = glance_t_to_codegen_t(X),
codegen_t_to_codegen_json_t(Ct, Field_name).
-spec gen_to_json(request:request()) -> internal@codegen@statements:gleam_statement().
gen_to_json(Req) ->
{request, Src_module_name, Type_name, Variant, _, _} = Req,
{function,
<<"to_json"/utf8>>,
[internal@codegen@statements:arg_typed(
<<"t"/utf8>>,
{anonymous_type,
<<<<(internal@path:basename(Src_module_name))/binary,
"."/utf8>>/binary,
Type_name/binary>>}
)],
[internal@codegen@statements:call(
<<"json.object"/utf8>>,
[internal@codegen@statements:list(
gleam@list:map(
erlang:element(3, Variant),
fun(Field) ->
case gleam@option:to_result(
erlang:element(2, Field),
nil
) of
{ok, Label} ->
{tuple_val,
[{string_val, Label},
serializer_of_t(
erlang:element(3, Field),
Label
)]};
_ ->
gleam@io:println_error(
<<<<"Variant "/utf8,
(erlang:element(2, Variant))/binary>>/binary,
" must have labels for all fields"/utf8>>
),
erlang:error(#{gleam_error => panic,
message => <<"missing label"/utf8>>,
module => <<"serializer"/utf8>>,
function => <<"gen_to_json"/utf8>>,
line => 149})
end
end
)
)]
)]}.
-spec gen_to_string(request:request()) -> internal@codegen@statements:gleam_statement().
gen_to_string(Req) ->
{request, Src_module_name, Type_name, _, _, _} = Req,
{function,
<<"to_string"/utf8>>,
[internal@codegen@statements:arg_typed(
<<"t"/utf8>>,
{anonymous_type,
<<<<(internal@path:basename(Src_module_name))/binary,
"."/utf8>>/binary,
Type_name/binary>>}
)],
[internal@codegen@statements:call(
<<"json.to_string"/utf8>>,
[internal@codegen@statements:call(
<<"to_json"/utf8>>,
[internal@codegen@statements:variable(<<"t"/utf8>>)]
)]
)]}.
-spec from(request:request()) -> binary().
from(Req) ->
_pipe = [gen_to_json(Req), gen_to_string(Req)],
_pipe@1 = gleam@list:map(_pipe, fun internal@codegen@statements:generate/1),
gleam@string:join(_pipe@1, <<"\n"/utf8>>).