Current section

Files

Jump to
libero src libero.erl
Raw

src/libero.erl

-module(libero).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/libero.gleam").
-export([qualified_atom_name/2, walk/1, generate_atoms/3, generate_wire_erl/2, generate_decoders_ffi/3, generate_decoders_gleam/0, generate_etf_codec_module/2, generate_json_contract/3, generate_json_contract_hash/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(
" Libero: seed-driven typed wire-contract generation for Gleam.\n"
"\n"
" Frameworks decide which application types cross the boundary. Libero walks\n"
" those seeded types and generates the ETF, JSON, and decoder artifacts used\n"
" by Rally.\n"
).
-file("src/libero.gleam", 18).
?DOC(" Build qualified atom names using the same logic as generated wire modules.\n").
-spec qualified_atom_name(binary(), binary()) -> binary().
qualified_atom_name(Module_path, Variant_name) ->
libero@walker:qualified_atom_name(Module_path, Variant_name).
-file("src/libero.gleam", 28).
?DOC(
" Walk the type graph from caller-provided seeds using this package's `src/`\n"
" directory as the source root. Rally runs this from the application root, so\n"
" its page-local wire types are discovered from the app's `src/`.\n"
).
-spec walk(list({binary(), binary()})) -> {ok,
list(libero@walker:discovered_type())} |
{error, list(libero@gen_error:gen_error())}.
walk(Seeds) ->
gleam@result:'try'(
begin
_pipe = libero@source:walk_directory(<<"./src"/utf8>>),
gleam@result:map_error(_pipe, fun(E) -> [E] end)
end,
fun(Files) -> libero@walker:walk(Seeds, Files) end
).
-file("src/libero.gleam", 41).
?DOC(
" Generate the Erlang atoms pre-registration file content.\n"
" Module name uses Gleam's @-separated convention, for example\n"
" `generated@libero_atoms`.\n"
).
-spec generate_atoms(
list(libero@walker:discovered_type()),
binary(),
gleam@option:option(binary())
) -> binary().
generate_atoms(Discovered, Atoms_module, Wire_module) ->
libero@codegen_atoms:generate(Discovered, Atoms_module, Wire_module).
-file("src/libero.gleam", 50).
?DOC(" Generate the per-type wire-transformer Erlang module.\n").
-spec generate_wire_erl(list(libero@walker:discovered_type()), binary()) -> {ok,
binary()} |
{error, libero@gen_error:gen_error()}.
generate_wire_erl(Discovered, Wire_module) ->
libero@etf@codegen_erl:generate(Wire_module, Discovered).
-file("src/libero.gleam", 59).
?DOC(
" Generate the JavaScript typed decoder FFI source.\n"
" `package` is the Gleam package name that owns the modules.\n"
).
-spec generate_decoders_ffi(
list(libero@walker:discovered_type()),
binary(),
list(binary())
) -> binary().
generate_decoders_ffi(Discovered, Package, Dependency_packages) ->
libero@codegen_decoders:generate_decoders_ffi(
Discovered,
<<"../../../"/utf8>>,
Package,
Dependency_packages
).
-file("src/libero.gleam", 73).
?DOC(" Generate the Gleam wrapper for the typed decoder FFI.\n").
-spec generate_decoders_gleam() -> binary().
generate_decoders_gleam() ->
libero@codegen_decoders:generate_decoders_gleam(<<"decoders_ffi.mjs"/utf8>>).
-file("src/libero.gleam", 78).
?DOC(" Generate a neutral ETF codec wrapper for generated application code.\n").
-spec generate_etf_codec_module(binary(), binary()) -> binary().
generate_etf_codec_module(Atoms_module, Decoders_module) ->
<<<<<<<<"//// Code generated by libero. DO NOT EDIT.
import "/utf8,
Decoders_module/binary>>/binary,
" as decoders
import libero/error.{type DecodeError}
import libero/etf/wire as etf_wire
pub fn ensure() -> Nil {
let _ = ensure_atoms()
let _ = decoders.ensure_decoders()
Nil
}
pub fn encode(value: a) -> BitArray {
ensure()
etf_wire.encode(value)
}
pub fn decode(bytes: BitArray) -> Result(a, DecodeError) {
ensure()
etf_wire.decode_safe(bytes)
}
@external(erlang, \""/utf8>>/binary,
Atoms_module/binary>>/binary,
"\", \"ensure\")
fn ensure_atoms() -> Nil {
Nil
}
"/utf8>>.
-file("src/libero.gleam", 112).
?DOC(" Generate a deterministic JSON contract artifact from discovered types.\n").
-spec generate_json_contract(
list(libero@walker:discovered_type()),
list(libero@json@contract:push_contract()),
list(libero@json@contract:ssr_model_contract())
) -> binary().
generate_json_contract(Discovered, Push_types, Ssr_models) ->
libero@json@contract:generate(Discovered, Push_types, Ssr_models).
-file("src/libero.gleam", 120).
-spec generate_json_contract_hash(
list(libero@walker:discovered_type()),
list(libero@json@contract:push_contract()),
list(libero@json@contract:ssr_model_contract())
) -> binary().
generate_json_contract_hash(Discovered, Push_types, Ssr_models) ->
libero@json@contract:generate_hash(Discovered, Push_types, Ssr_models).