Current section
Files
Jump to
Current section
Files
src/atproto_codegen@emit@zero.erl
-module(atproto_codegen@emit@zero).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/atproto_codegen/emit/zero.gleam").
-export([error_to_string/1, compute/1, needs_zero/2, choose_fallback/3]).
-export_type([zero_plan/0, zero_error/0]).
-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(false).
-opaque zero_plan() :: {zero_plan,
gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()),
gleam@dict:dict({binary(), binary()}, boolean()),
gleam@dict:dict({binary(), list(binary())}, binary())}.
-type zero_error() :: {unzeroable_closed_union, binary(), list(binary())}.
-file("src/atproto_codegen/emit/zero.gleam", 32).
?DOC(false).
-spec error_to_string(zero_error()) -> binary().
error_to_string(Err) ->
case Err of
{unzeroable_closed_union, Nsid, Refs} ->
<<<<<<<<"closed union in "/utf8, Nsid/binary>>/binary,
" has no member with a constructible zero value (refs: "/utf8>>/binary,
(gleam@string:join(Refs, <<", "/utf8>>))/binary>>/binary,
")"/utf8>>
end.
-file("src/atproto_codegen/emit/zero.gleam", 90).
?DOC(false).
-spec key_of(binary(), binary()) -> {binary(), binary()}.
key_of(Current, Ref) ->
R = atproto_codegen@naming:parse_ref(Current, Ref),
{erlang:element(2, R), erlang:element(3, R)}.
-file("src/atproto_codegen/emit/zero.gleam", 214).
?DOC(false).
-spec def_nsid(atproto_codegen@lower:emittable_def()) -> binary().
def_nsid(Def) ->
case Def of
{emittable_record, Nsid, _} ->
Nsid;
{emittable_object, Nsid@1, _, _} ->
Nsid@1
end.
-file("src/atproto_codegen/emit/zero.gleam", 194).
?DOC(false).
-spec field_resolvable(
gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()),
binary(),
atproto_codegen@lower:flat_type(),
gleam@set:set({binary(), binary()}),
gleam@dict:dict({binary(), binary()}, boolean())
) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}.
field_resolvable(Defs, Current, Ft, Visiting, Memo) ->
case Ft of
{t_ref, Ref} ->
resolve_key(Defs, key_of(Current, Ref), Visiting, Memo);
{t_union, Refs, closed} ->
case resolve_fallback(Defs, Current, Refs, Visiting, Memo) of
{{some, _}, Memo2} ->
{true, Memo2};
{none, Memo2@1} ->
{false, Memo2@1}
end;
{t_unsupported, _} ->
{false, Memo};
_ ->
{true, Memo}
end.
-file("src/atproto_codegen/emit/zero.gleam", 159).
?DOC(false).
-spec resolve_def(
gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()),
{binary(), binary()},
gleam@set:set({binary(), binary()}),
gleam@dict:dict({binary(), binary()}, boolean())
) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}.
resolve_def(Defs, Key, Visiting, Memo) ->
case gleam_stdlib:map_get(Defs, Key) of
{error, nil} ->
{false, gleam@dict:insert(Memo, Key, false)};
{ok, Def} ->
Visiting2 = gleam@set:insert(Visiting, Key),
Own_nsid = def_nsid(Def),
{Ok, Memo2} = gleam@list:fold(
atproto_codegen@lower:emittable_properties(Def),
{true, Memo},
fun(Acc, Field) ->
{Ok_acc, Memo_acc} = Acc,
case {Ok_acc, erlang:element(4, Field)} of
{false, _} ->
Acc;
{_, false} ->
Acc;
{true, true} ->
field_resolvable(
Defs,
Own_nsid,
erlang:element(3, Field),
Visiting2,
Memo_acc
)
end
end
),
{Ok, gleam@dict:insert(Memo2, Key, Ok)}
end.
-file("src/atproto_codegen/emit/zero.gleam", 143).
?DOC(false).
-spec resolve_key(
gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()),
{binary(), binary()},
gleam@set:set({binary(), binary()}),
gleam@dict:dict({binary(), binary()}, boolean())
) -> {boolean(), gleam@dict:dict({binary(), binary()}, boolean())}.
resolve_key(Defs, Key, Visiting, Memo) ->
case gleam_stdlib:map_get(Memo, Key) of
{ok, Known} ->
{Known, Memo};
{error, nil} ->
case gleam@set:contains(Visiting, Key) of
true ->
{false, Memo};
false ->
resolve_def(Defs, Key, Visiting, Memo)
end
end.
-file("src/atproto_codegen/emit/zero.gleam", 124).
?DOC(false).
-spec resolve_fallback(
gleam@dict:dict({binary(), binary()}, atproto_codegen@lower:emittable_def()),
binary(),
list(binary()),
gleam@set:set({binary(), binary()}),
gleam@dict:dict({binary(), binary()}, boolean())
) -> {gleam@option:option(binary()),
gleam@dict:dict({binary(), binary()}, boolean())}.
resolve_fallback(Defs, Current, Refs, Visiting, Memo) ->
case Refs of
[] ->
{none, Memo};
[Ref | Rest] ->
{Ok, Memo2} = resolve_key(
Defs,
key_of(Current, Ref),
Visiting,
Memo
),
case Ok of
true ->
{{some, Ref}, Memo2};
false ->
resolve_fallback(Defs, Current, Rest, Visiting, Memo2)
end
end.
-file("src/atproto_codegen/emit/zero.gleam", 110).
?DOC(false).
-spec closed_unions(list(atproto_codegen@lower:flat_lexicon())) -> list({binary(),
list(binary())}).
closed_unions(Lexicons) ->
gleam@list:flat_map(
Lexicons,
fun(Lex) ->
_pipe = atproto_codegen@lower:codec_units(erlang:element(4, Lex)),
gleam@list:filter_map(_pipe, fun(Unit) -> case Unit of
{union_unit, _, _, Refs, closed} ->
{ok, {erlang:element(2, Lex), Refs}};
_ ->
{error, nil}
end end)
end
).
-file("src/atproto_codegen/emit/zero.gleam", 95).
?DOC(false).
-spec key_of_def(atproto_codegen@lower:emittable_def()) -> {binary(), binary()}.
key_of_def(Def) ->
case Def of
{emittable_record, Nsid, _} ->
{Nsid, <<"main"/utf8>>};
{emittable_object, Nsid@1, Name, _} ->
{Nsid@1, Name}
end.
-file("src/atproto_codegen/emit/zero.gleam", 102).
?DOC(false).
-spec index_defs(list(atproto_codegen@lower:flat_lexicon())) -> gleam@dict:dict({binary(),
binary()}, atproto_codegen@lower:emittable_def()).
index_defs(Lexicons) ->
_pipe = Lexicons,
_pipe@1 = gleam@list:flat_map(_pipe, fun(Lex) -> erlang:element(4, Lex) end),
_pipe@2 = gleam@list:filter_map(
_pipe@1,
fun atproto_codegen@lower:to_emittable/1
),
_pipe@3 = gleam@list:map(_pipe@2, fun(Def) -> {key_of_def(Def), Def} end),
maps:from_list(_pipe@3).
-file("src/atproto_codegen/emit/zero.gleam", 45).
?DOC(false).
-spec compute(list(atproto_codegen@lower:flat_lexicon())) -> {ok, zero_plan()} |
{error, zero_error()}.
compute(Lexicons) ->
Defs = index_defs(Lexicons),
gleam@result:'try'(
gleam@list:try_fold(
closed_unions(Lexicons),
{maps:new(), maps:new()},
fun(Acc, U) ->
{Memo, Fallbacks} = Acc,
{Current, Refs} = U,
{Chosen, Memo2} = resolve_fallback(
Defs,
Current,
Refs,
gleam@set:new(),
Memo
),
case Chosen of
{some, Ref} ->
{ok,
{Memo2,
gleam@dict:insert(
Fallbacks,
{Current, Refs},
Ref
)}};
none ->
{error, {unzeroable_closed_union, Current, Refs}}
end
end
),
fun(_use0) ->
{Resolvable, Fallbacks@1} = _use0,
{ok, {zero_plan, Defs, Resolvable, Fallbacks@1}}
end
).
-file("src/atproto_codegen/emit/zero.gleam", 67).
?DOC(false).
-spec needs_zero(zero_plan(), atproto_codegen@lower:emittable_def()) -> boolean().
needs_zero(Plan, Def) ->
gleam_stdlib:map_get(erlang:element(3, Plan), key_of_def(Def)) =:= {ok,
true}.
-file("src/atproto_codegen/emit/zero.gleam", 75).
?DOC(false).
-spec choose_fallback(zero_plan(), binary(), list(binary())) -> binary().
choose_fallback(Plan, Current, Refs) ->
case gleam_stdlib:map_get(erlang:element(4, Plan), {Current, Refs}) of
{ok, Ref} ->
Ref;
{error, nil} ->
case Refs of
[First | _] ->
First;
[] ->
Current
end
end.