Current section

Files

Jump to
libero src libero@codegen_atoms.erl
Raw

src/libero@codegen_atoms.erl

-module(libero@codegen_atoms).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/libero/codegen_atoms.gleam").
-export([generate/3]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
?MODULEDOC(" Erlang atom pre-registration for generated wire codecs.\n").
-file("src/libero/codegen_atoms.gleam", 9).
-spec generate(
list(libero@walker:discovered_type()),
binary(),
gleam@option:option(binary())
) -> binary().
generate(Discovered, Atoms_module, Wire_module) ->
Framework_atoms = [<<"ok"/utf8>>,
<<"error"/utf8>>,
<<"some"/utf8>>,
<<"none"/utf8>>,
<<"nil"/utf8>>,
<<"true"/utf8>>,
<<"false"/utf8>>,
<<"malformed_request"/utf8>>,
<<"unknown_function"/utf8>>,
<<"internal_error"/utf8>>,
<<"decode_error"/utf8>>],
Variant_atoms = gleam@list:flat_map(
Discovered,
fun(Dt) ->
gleam@list:flat_map(
erlang:element(5, Dt),
fun(V) ->
{_, Hash} = libero@wire_identity:wire_identity(
erlang:element(2, V),
erlang:element(3, V),
erlang:element(7, V)
),
[libero@walker:to_snake_case(erlang:element(3, V)), Hash]
end
)
end
),
All_atoms = begin
_pipe = lists:append(Framework_atoms, Variant_atoms),
_pipe@1 = gleam@list:unique(_pipe),
gleam@list:sort(_pipe@1, fun gleam@string:compare/2)
end,
Atom_list = begin
_pipe@2 = gleam@list:map(
All_atoms,
fun(Atom) ->
<<<<" <<\""/utf8, Atom/binary>>/binary, "\">>"/utf8>>
end
),
gleam@string:join(_pipe@2, <<",\n"/utf8>>)
end,
<<<<<<<<<<<<"%% Code generated by libero. DO NOT EDIT.
%%
%% Pre-registers atoms that may appear in ETF payloads so
%% binary_to_term([safe]) can decode them without rejecting unknown atoms.
%%
%% ensure/0 uses persistent_term as a one-shot guard so the
%% binary_to_atom calls only run once per VM lifetime.
-module("/utf8,
Atoms_module/binary>>/binary,
").
-export([ensure/0]).
ensure() ->
case persistent_term:get({?MODULE, done}, false) of
true -> nil;
false -> do_ensure()
end.
do_ensure() ->
lists:foreach(fun(B) -> binary_to_atom(B) end, [
"/utf8>>/binary,
Atom_list/binary>>/binary,
"
]),
"/utf8>>/binary,
(case Wire_module of
{some, Mod} ->
<<<<"persistent_term:put({libero, wire_module}, '"/utf8,
Mod/binary>>/binary,
"'),\n "/utf8>>;
none ->
<<""/utf8>>
end)/binary>>/binary,
"persistent_term:put({?MODULE, done}, true),
nil.
"/utf8>>.