Current section
Files
Jump to
Current section
Files
src/atproto_codegen@plugins@xrpc_client.erl
-module(atproto_codegen@plugins@xrpc_client).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/atproto_codegen/plugins/xrpc_client.gleam").
-export([plugin/0]).
-export_type([send/0, out_plan/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(
" The `xrpc-client` plugin: one whole module of typed Gleam functions that\n"
" call the corpus's query/procedure methods over HTTP through\n"
" `atproto/xrpc`. Unlike `types`/`decode-json` (which contribute per-unit\n"
" `parts` the host interleaves), this plugin owns the entire client module\n"
" and emits a single `WholeFile` (its own banner, doc, imports, and every\n"
" method's params/input/output types, typed error union, and function).\n"
"\n"
" Refs in a method's body resolve against that method's own nsid and are\n"
" then rendered fully qualified (the client module imports every referenced\n"
" generated module), reusing `emit/def` + `emit/exprs` against a synthetic\n"
" object with a sentinel current-module so their same-module shortcut never\n"
" fires. Names derive from the method nsid via `naming.module_alias`, the\n"
" same pattern the rest of the tool uses.\n"
).
-type send() :: get | {post_json, binary()} | {post_bits, binary()}.
-type out_plan() :: {out_value, binary(), binary(), list(binary())} | out_nil.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 94).
-spec absolute(binary(), binary()) -> binary().
absolute(Nsid, Ref) ->
R = atproto_codegen@naming:parse_ref(Nsid, Ref),
<<<<(erlang:element(2, R))/binary, "#"/utf8>>/binary,
(erlang:element(3, R))/binary>>.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 84).
?DOC(" Rewrite every ref to its absolute `nsid#def` form, so the reused `emit`/`exprs` renderers (run with a sentinel current-module) emit a fully qualified name.\n").
-spec resolve_refs(binary(), atproto_codegen@lower:flat_type()) -> atproto_codegen@lower:flat_type().
resolve_refs(Nsid, Ft) ->
case Ft of
{t_ref, Ref} ->
{t_ref, absolute(Nsid, Ref)};
{t_array, Inner} ->
{t_array, resolve_refs(Nsid, Inner)};
{t_union, Refs, Closed} ->
{t_union,
gleam@list:map(
Refs,
fun(_capture) -> absolute(Nsid, _capture) end
),
Closed};
Other ->
Other
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 569).
-spec method_ref_nsids(atproto_codegen@lower:method()) -> list(binary()).
method_ref_nsids(M) ->
Body_nsids = fun(Body) -> case Body of
{some, {flat_body, _, {some, {body_ref, Ref}}}} ->
R = atproto_codegen@naming:parse_ref(erlang:element(2, M), Ref),
[erlang:element(2, R)];
{some, {flat_body, _, {some, {body_inline, Props}}}} ->
gleam@list:flat_map(
Props,
fun(P) ->
atproto_codegen@module_header:referenced_nsids(
resolve_refs(
erlang:element(2, M),
erlang:element(3, P)
)
)
end
);
_ ->
[]
end end,
lists:append(
Body_nsids(erlang:element(5, M)),
Body_nsids(erlang:element(6, M))
).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 563).
-spec fields_use_flatten(list(atproto_codegen@lower:flat_field())) -> boolean().
fields_use_flatten(Props) ->
Optional = gleam@list:count(Props, fun(P) -> not erlang:element(4, P) end),
Required = erlang:length(Props) - Optional,
(Optional >= 1) andalso ((Required >= 1) orelse (Optional >= 2)).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 547).
-spec decodes_output(atproto_codegen@lower:method()) -> boolean().
decodes_output(M) ->
case erlang:element(6, M) of
{some, {flat_body, _, {some, {body_ref, _}}}} ->
true;
{some, {flat_body, _, {some, {body_inline, _}}}} ->
true;
_ ->
false
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 539).
-spec uses_post_json(atproto_codegen@lower:method()) -> boolean().
uses_post_json(M) ->
case {erlang:element(3, M), erlang:element(5, M)} of
{method_procedure, {some, {flat_body, _, none}}} ->
false;
{method_procedure, _} ->
true;
{method_query, _} ->
false
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 555).
-spec has_int(atproto_codegen@lower:flat_type()) -> boolean().
has_int(Ft) ->
case Ft of
t_int ->
true;
{t_array, Inner} ->
has_int(Inner);
_ ->
false
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 99).
-spec resolve_field(binary(), atproto_codegen@lower:flat_field()) -> atproto_codegen@lower:flat_field().
resolve_field(Nsid, Field) ->
{flat_field,
erlang:element(2, Field),
resolve_refs(Nsid, erlang:element(3, Field)),
erlang:element(4, Field),
erlang:element(5, Field)}.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 531).
-spec output_inline(atproto_codegen@lower:method()) -> {ok,
list(atproto_codegen@lower:flat_field())} |
{error, nil}.
output_inline(M) ->
case erlang:element(6, M) of
{some, {flat_body, _, {some, {body_inline, Props}}}} ->
{ok,
gleam@list:map(
Props,
fun(_capture) ->
resolve_field(erlang:element(2, M), _capture)
end
)};
_ ->
{error, nil}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 523).
-spec input_inline(atproto_codegen@lower:method()) -> {ok,
list(atproto_codegen@lower:flat_field())} |
{error, nil}.
input_inline(M) ->
case erlang:element(5, M) of
{some, {flat_body, _, {some, {body_inline, Props}}}} ->
{ok,
gleam@list:map(
Props,
fun(_capture) ->
resolve_field(erlang:element(2, M), _capture)
end
)};
_ ->
{error, nil}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 450).
-spec imports(
atproto_codegen@config:config(),
list(atproto_codegen@lower:method())
) -> binary().
imports(Cfg, Methods) ->
Inline_inputs = gleam@list:filter_map(Methods, fun input_inline/1),
Inline_outputs = gleam@list:filter_map(Methods, fun output_inline/1),
All_inline = lists:append(lists:append(Inline_inputs, Inline_outputs)),
Has_params = gleam@list:any(
Methods,
fun(M) -> erlang:element(4, M) /= [] end
),
Has_int_param = gleam@list:any(
Methods,
fun(M@1) ->
gleam@list:any(
erlang:element(4, M@1),
fun(P) -> has_int(erlang:element(3, P)) end
)
end
),
Has_json = gleam@list:any(Methods, fun uses_post_json/1),
Has_decode = gleam@list:any(Methods, fun decodes_output/1),
Has_blob = gleam@list:any(
All_inline,
fun(F) ->
atproto_codegen@emit@exprs:type_uses_blob(erlang:element(3, F))
end
),
Has_unknown = gleam@list:any(
All_inline,
fun(F@1) ->
atproto_codegen@emit@exprs:type_uses_unknown(erlang:element(3, F@1))
end
),
Has_helper = gleam@list:any(
All_inline,
fun(F@2) ->
atproto_codegen@emit@exprs:type_uses_helper(erlang:element(3, F@2))
end
),
Has_opt_input = gleam@list:any(
Inline_inputs,
fun(Props) ->
gleam@list:any(Props, fun(P@1) -> not erlang:element(4, P@1) end)
end
),
List_needed = Has_params orelse gleam@list:any(
Inline_inputs,
fun fields_use_flatten/1
),
Internal_needed = Has_opt_input orelse Has_helper,
Std = begin
_pipe = [case Has_blob of
true ->
[<<"import atproto/blob"/utf8>>];
false ->
[]
end, case Has_decode of
true ->
[<<"import gleam/dynamic/decode"/utf8>>];
false ->
[]
end, case Has_unknown of
true ->
[<<"import gleam/dynamic"/utf8>>];
false ->
[]
end, case Has_int_param of
true ->
[<<"import gleam/int"/utf8>>];
false ->
[]
end, case Has_json of
true ->
[<<"import gleam/json"/utf8>>];
false ->
[]
end, case List_needed of
true ->
[<<"import gleam/list"/utf8>>];
false ->
[]
end, [<<"import gleam/option.{type Option}"/utf8>>], [<<"import gleam/result"/utf8>>], case Has_params of
true ->
[<<"import gleam/uri"/utf8>>];
false ->
[]
end, [<<"import atproto/xrpc"/utf8>>], case Internal_needed of
true ->
[<<<<"import "/utf8, (erlang:element(4, Cfg))/binary>>/binary,
"/internal"/utf8>>];
false ->
[]
end],
lists:append(_pipe)
end,
Ext = begin
_pipe@1 = Methods,
_pipe@2 = gleam@list:flat_map(_pipe@1, fun method_ref_nsids/1),
_pipe@3 = gleam@list:unique(_pipe@2),
_pipe@4 = gleam@list:sort(_pipe@3, fun gleam@string:compare/2),
gleam@list:map(
_pipe@4,
fun(_capture) ->
atproto_codegen@module_header:ext_import_line(Cfg, _capture)
end
)
end,
<<(gleam@string:join(lists:append(Std, Ext), <<"\n"/utf8>>))/binary,
"\n"/utf8>>.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 73).
-spec base_snake(atproto_codegen@config:config(), binary()) -> binary().
base_snake(Cfg, Nsid) ->
atproto_codegen@naming:module_alias(erlang:element(5, Cfg), Nsid).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 77).
-spec base_pascal(atproto_codegen@config:config(), binary()) -> binary().
base_pascal(Cfg, Nsid) ->
justin:pascal_case(base_snake(Cfg, Nsid)).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 408).
-spec error_map(atproto_codegen@config:config(), atproto_codegen@lower:method()) -> binary().
error_map(Cfg, M) ->
Base = base_pascal(Cfg, erlang:element(2, M)),
Map_fn = <<<<"map_"/utf8, (base_snake(Cfg, erlang:element(2, M)))/binary>>/binary,
"_error"/utf8>>,
Bad = case erlang:element(7, M) of
[] ->
<<<<" xrpc.BadStatus(status, _, message, body) -> "/utf8,
Base/binary>>/binary,
"Unexpected(status, message, body)"/utf8>>;
Errs ->
Arms = gleam@list:map(
Errs,
fun(E) ->
<<<<<<<<<<" option.Some(\""/utf8,
(atproto_codegen@emit@exprs:escape(
erlang:element(2, E)
))/binary>>/binary,
"\") -> "/utf8>>/binary,
Base/binary>>/binary,
(justin:pascal_case(erlang:element(2, E)))/binary>>/binary,
"(message)"/utf8>>
end
),
<<<<<<<<" xrpc.BadStatus(status, error, message, body) ->\n case error {\n"/utf8,
(gleam@string:join(Arms, <<"\n"/utf8>>))/binary>>/binary,
"\n _ -> "/utf8>>/binary,
Base/binary>>/binary,
"Unexpected(status, message, body)\n }"/utf8>>
end,
<<<<<<<<<<<<<<<<<<<<<<<<"fn "/utf8, Map_fn/binary>>/binary,
"(err: xrpc.XrpcError) -> "/utf8>>/binary,
Base/binary>>/binary,
"Error {\n case err {\n"/utf8>>/binary,
" xrpc.RequestFailed(_) -> "/utf8>>/binary,
Base/binary>>/binary,
"Transport(err)\n"/utf8>>/binary,
" xrpc.DecodeFailed(_) -> "/utf8>>/binary,
Base/binary>>/binary,
"Transport(err)\n"/utf8>>/binary,
Bad/binary>>/binary,
"\n }\n}"/utf8>>.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 393).
-spec error_type(
atproto_codegen@config:config(),
atproto_codegen@lower:method()
) -> binary().
error_type(Cfg, M) ->
Base = base_pascal(Cfg, erlang:element(2, M)),
Named = gleam@list:map(
erlang:element(7, M),
fun(E) ->
<<<<Base/binary, (justin:pascal_case(erlang:element(2, E)))/binary>>/binary,
"(message: Option(String))"/utf8>>
end
),
Variants = begin
_pipe = [<<Base/binary, "Transport(xrpc.XrpcError)"/utf8>>,
<<Base/binary,
"Unexpected(status: Int, message: Option(String), body: String)"/utf8>>],
lists:append(_pipe, Named)
end,
<<<<<<<<"pub type "/utf8, Base/binary>>/binary, "Error {\n "/utf8>>/binary,
(gleam@string:join(Variants, <<"\n "/utf8>>))/binary>>/binary,
"\n}"/utf8>>.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 383).
-spec url_line(atproto_codegen@lower:method(), gleam@option:option(binary())) -> binary().
url_line(M, Query_line) ->
case Query_line of
{some, Q} ->
<<<<<<Q/binary, " let url = service <> \"/xrpc/"/utf8>>/binary,
(erlang:element(2, M))/binary>>/binary,
"?\" <> query\n"/utf8>>;
none ->
<<<<" let url = service <> \"/xrpc/"/utf8,
(erlang:element(2, M))/binary>>/binary,
"\"\n"/utf8>>
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 163).
-spec append_opt(list(binary()), gleam@option:option(binary())) -> list(binary()).
append_opt(Items, Extra) ->
case Extra of
{some, X} ->
lists:append(Items, [X]);
none ->
Items
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 362).
-spec chain_expr(binary(), binary(), out_plan()) -> binary().
chain_expr(Call, Map_fn, Out) ->
case Out of
out_nil ->
<<<<<<<<" "/utf8, Call/binary>>/binary,
"\n |> result.map_error("/utf8>>/binary,
Map_fn/binary>>/binary,
")\n |> result.replace(Nil)"/utf8>>;
{out_value, _, Decoder, _} ->
<<<<<<<<<<<<<<<<" "/utf8, Call/binary>>/binary,
"\n |> result.map_error("/utf8>>/binary,
Map_fn/binary>>/binary,
")\n |> result.try(fn(resp) {\n xrpc.parse(resp.body, "/utf8>>/binary,
Decoder/binary>>/binary,
")\n |> result.map_error("/utf8>>/binary,
Map_fn/binary>>/binary,
")\n })"/utf8>>
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 351).
-spec call_expr(atproto_codegen@lower:method(), send()) -> binary().
call_expr(M, Send) ->
case {erlang:element(3, M), Send} of
{method_query, _} ->
<<"xrpc.get(client, url, token)"/utf8>>;
{method_procedure, {post_json, Body}} ->
<<<<"xrpc.post_json(client, url, token, "/utf8, Body/binary>>/binary,
")"/utf8>>;
{method_procedure, {post_bits, Ct}} ->
<<<<"xrpc.post_bits(client, url, token, body, \""/utf8,
(atproto_codegen@emit@exprs:escape(Ct))/binary>>/binary,
"\")"/utf8>>;
{method_procedure, get} ->
<<"xrpc.get(client, url, token)"/utf8>>
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 341).
-spec renderable(atproto_codegen@lower:flat_type()) -> boolean().
renderable(Ft) ->
case Ft of
{t_union, _, _} ->
false;
{t_unsupported, _} ->
false;
{t_array, Inner} ->
renderable(Inner);
_ ->
true
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 326).
?DOC(" Resolve refs to absolute form and reject body fields the client renderers can't handle (unions, unsupported types), naming the method.\n").
-spec resolve_body(binary(), list(atproto_codegen@lower:flat_field())) -> {ok,
list(atproto_codegen@lower:flat_field())} |
{error, atproto_codegen@plugin:codegen_error()}.
resolve_body(Nsid, Props) ->
Resolved = gleam@list:map(
Props,
fun(_capture) -> resolve_field(Nsid, _capture) end
),
case gleam@list:find(
Resolved,
fun(F) -> not renderable(erlang:element(3, F)) end
) of
{ok, Bad} ->
{error,
{plugin_failure,
<<"xrpc-client"/utf8>>,
<<<<<<Nsid/binary, ": unrenderable body field `"/utf8>>/binary,
(erlang:element(2, Bad))/binary>>/binary,
"`"/utf8>>}};
{error, nil} ->
{ok, Resolved}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 290).
-spec output_section(
atproto_codegen@config:config(),
atproto_codegen@lower:method()
) -> {ok, {out_plan(), list(binary())}} |
{error, atproto_codegen@plugin:codegen_error()}.
output_section(Cfg, M) ->
case erlang:element(6, M) of
none ->
{ok, {out_nil, []}};
{some, {flat_body, _, none}} ->
{ok, {out_nil, []}};
{some, {flat_body, _, {some, {body_ref, Ref}}}} ->
Abs = absolute(erlang:element(2, M), Ref),
Ty = atproto_codegen@emit@exprs:gleam_type(
Cfg,
<<""/utf8>>,
<<""/utf8>>,
{t_ref, Abs}
),
Decoder = atproto_codegen@emit@exprs:decoder_expr(
Cfg,
<<""/utf8>>,
<<""/utf8>>,
{t_ref, Abs}
),
{ok, {{out_value, Ty, Decoder, []}, []}};
{some, {flat_body, _, {some, {body_inline, Props}}}} ->
Type_name = <<(base_pascal(Cfg, erlang:element(2, M)))/binary,
"Output"/utf8>>,
gleam@result:'try'(
resolve_body(erlang:element(2, M), Props),
fun(Resolved) ->
Def = {flat_object, <<""/utf8>>, Type_name, Resolved},
Type_def = atproto_codegen@emit@def:emit_type(
Cfg,
<<""/utf8>>,
Def,
Type_name,
Resolved
),
Decoder_def = atproto_codegen@emit@def:emit_decoder(
Cfg,
<<""/utf8>>,
Def,
Type_name,
Resolved
),
{ok,
{{out_value,
Type_name,
<<(justin:snake_case(Type_name))/binary,
"_decoder()"/utf8>>,
[Type_def, Decoder_def]},
[Type_def, Decoder_def]}}
end
);
{some, {flat_body, _, {some, {body_unsupported, Reason}}}} ->
{error,
{plugin_failure,
<<"xrpc-client"/utf8>>,
<<<<<<(erlang:element(2, M))/binary, ": "/utf8>>/binary,
Reason/binary>>/binary,
" (output)"/utf8>>}}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 281).
-spec encoding_of(gleam@option:option(atproto_codegen@lower:flat_body())) -> binary().
encoding_of(Body) ->
case Body of
{some, {flat_body, Encoding, _}} ->
Encoding;
none ->
<<"application/octet-stream"/utf8>>
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 246).
-spec input_section(
atproto_codegen@config:config(),
atproto_codegen@lower:method()
) -> {ok, {send(), gleam@option:option(binary()), list(binary())}} |
{error, atproto_codegen@plugin:codegen_error()}.
input_section(Cfg, M) ->
case {erlang:element(3, M), erlang:element(5, M)} of
{method_query, _} ->
{ok, {get, none, []}};
{method_procedure, none} ->
{ok, {{post_json, <<"json.object([])"/utf8>>}, none, []}};
{method_procedure, {some, {flat_body, _, none}}} ->
{ok,
{{post_bits, encoding_of(erlang:element(5, M))},
{some, <<"body: BitArray"/utf8>>},
[]}};
{method_procedure, {some, {flat_body, _, {some, {body_ref, Ref}}}}} ->
Abs = absolute(erlang:element(2, M), Ref),
Ty = atproto_codegen@emit@exprs:gleam_type(
Cfg,
<<""/utf8>>,
<<""/utf8>>,
{t_ref, Abs}
),
Encoder = atproto_codegen@emit@exprs:encoder_expr(
Cfg,
<<""/utf8>>,
<<""/utf8>>,
{t_ref, Abs}
),
{ok,
{{post_json, <<Encoder/binary, "(input)"/utf8>>},
{some, <<"input: "/utf8, Ty/binary>>},
[]}};
{method_procedure, {some, {flat_body, _, {some, {body_inline, Props}}}}} ->
Type_name = <<(base_pascal(Cfg, erlang:element(2, M)))/binary,
"Input"/utf8>>,
gleam@result:'try'(
resolve_body(erlang:element(2, M), Props),
fun(Resolved) ->
Def = {flat_object, <<""/utf8>>, Type_name, Resolved},
Type_def = atproto_codegen@emit@def:emit_type(
Cfg,
<<""/utf8>>,
Def,
Type_name,
Resolved
),
Fields = atproto_codegen@emit@def:emit_fields(
Cfg,
<<""/utf8>>,
Def,
Type_name,
Resolved
),
Encoder@1 = atproto_codegen@emit@def:emit_encoder(
<<""/utf8>>,
Type_name,
false
),
{ok,
{{post_json,
<<<<"encode_"/utf8,
(justin:snake_case(Type_name))/binary>>/binary,
"(input)"/utf8>>},
{some, <<"input: "/utf8, Type_name/binary>>},
[Type_def, Fields, Encoder@1]}}
end
);
{method_procedure,
{some, {flat_body, _, {some, {body_unsupported, Reason}}}}} ->
{error,
{plugin_failure,
<<"xrpc-client"/utf8>>,
<<<<<<(erlang:element(2, M))/binary, ": "/utf8>>/binary,
Reason/binary>>/binary,
" (input)"/utf8>>}}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 235).
-spec scalar_to_string(atproto_codegen@lower:flat_type(), binary()) -> {ok,
binary()} |
{error, nil}.
scalar_to_string(Ft, Var) ->
case Ft of
t_string ->
{ok, Var};
t_int ->
{ok, <<<<"int.to_string("/utf8, Var/binary>>/binary, ")"/utf8>>};
t_bool ->
{ok,
<<<<"case "/utf8, Var/binary>>/binary,
" { True -> \"true\" False -> \"false\" }"/utf8>>};
_ ->
{error, nil}
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 200).
-spec param_piece(atproto_codegen@lower:flat_field()) -> {ok, binary()} |
{error, nil}.
param_piece(Field) ->
Key = atproto_codegen@emit@exprs:escape(erlang:element(2, Field)),
Acc = <<"params."/utf8,
(atproto_codegen@naming:field_name(erlang:element(2, Field)))/binary>>,
case {erlang:element(3, Field), erlang:element(4, Field)} of
{{t_array, Inner}, true} ->
gleam@result:map(
scalar_to_string(Inner, <<"v"/utf8>>),
fun(S) ->
<<<<<<<<<<<<"list.map("/utf8, Acc/binary>>/binary,
", fn(v) { #(\""/utf8>>/binary,
Key/binary>>/binary,
"\", "/utf8>>/binary,
S/binary>>/binary,
") })"/utf8>>
end
);
{{t_array, Inner@1}, false} ->
gleam@result:map(
scalar_to_string(Inner@1, <<"v"/utf8>>),
fun(S@1) ->
<<<<<<<<<<<<"case "/utf8, Acc/binary>>/binary,
" { option.Some(vs) -> list.map(vs, fn(v) { #(\""/utf8>>/binary,
Key/binary>>/binary,
"\", "/utf8>>/binary,
S@1/binary>>/binary,
") }) option.None -> [] }"/utf8>>
end
);
{Ft, true} ->
gleam@result:map(
scalar_to_string(Ft, Acc),
fun(S@2) ->
<<<<<<<<"[#(\""/utf8, Key/binary>>/binary, "\", "/utf8>>/binary,
S@2/binary>>/binary,
")]"/utf8>>
end
);
{Ft@1, false} ->
gleam@result:map(
scalar_to_string(Ft@1, <<"v"/utf8>>),
fun(S@3) ->
<<<<<<<<<<<<"case "/utf8, Acc/binary>>/binary,
" { option.Some(v) -> [#(\""/utf8>>/binary,
Key/binary>>/binary,
"\", "/utf8>>/binary,
S@3/binary>>/binary,
")] option.None -> [] }"/utf8>>
end
)
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 172).
-spec params_section(
atproto_codegen@config:config(),
atproto_codegen@lower:method()
) -> {ok,
{list(binary()),
gleam@option:option(binary()),
gleam@option:option(binary())}} |
{error, atproto_codegen@plugin:codegen_error()}.
params_section(Cfg, M) ->
case erlang:element(4, M) of
[] ->
{ok, {[], none, none}};
Fields ->
Type_name = <<(base_pascal(Cfg, erlang:element(2, M)))/binary,
"Params"/utf8>>,
Def = {flat_object, <<""/utf8>>, Type_name, Fields},
Type_def = atproto_codegen@emit@def:emit_type(
Cfg,
<<""/utf8>>,
Def,
Type_name,
Fields
),
gleam@result:'try'(
gleam@list:try_map(Fields, fun(F) -> _pipe = param_piece(F),
gleam@result:replace_error(
_pipe,
{plugin_failure,
<<"xrpc-client"/utf8>>,
<<<<<<(erlang:element(2, M))/binary,
": unsupported param type on `"/utf8>>/binary,
(erlang:element(2, F))/binary>>/binary,
"`"/utf8>>}
) end),
fun(Pieces) ->
Query = <<<<" let query = uri.query_to_string(list.flatten(["/utf8,
(gleam@string:join(Pieces, <<", "/utf8>>))/binary>>/binary,
"]))\n"/utf8>>,
{ok,
{[Type_def],
{some, <<"params: "/utf8, Type_name/binary>>},
{some, Query}}}
end
)
end.
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 116).
-spec method_block(
atproto_codegen@config:config(),
atproto_codegen@lower:method()
) -> {ok, binary()} | {error, atproto_codegen@plugin:codegen_error()}.
method_block(Cfg, M) ->
Base_p = base_pascal(Cfg, erlang:element(2, M)),
Map_fn = <<<<"map_"/utf8, (base_snake(Cfg, erlang:element(2, M)))/binary>>/binary,
"_error"/utf8>>,
gleam@result:'try'(
params_section(Cfg, M),
fun(Params) ->
gleam@result:'try'(
input_section(Cfg, M),
fun(Input) ->
gleam@result:'try'(
output_section(Cfg, M),
fun(Output) ->
{Params_defs, Params_decl, Query_line} = Params,
{Send, Input_decl, Input_defs} = Input,
{Out_plan, Output_defs} = Output,
Call = call_expr(M, Send),
Ret_type@1 = case Out_plan of
{out_value, Ret_type, _, _} ->
Ret_type;
out_nil ->
<<"Nil"/utf8>>
end,
Chain = chain_expr(Call, Map_fn, Out_plan),
Decls = begin
_pipe = [<<"client: xrpc.Client"/utf8>>,
<<"service: String"/utf8>>],
_pipe@1 = append_opt(_pipe, Params_decl),
_pipe@2 = append_opt(_pipe@1, Input_decl),
lists:append(
_pipe@2,
[<<"token: Option(String)"/utf8>>]
)
end,
Url_line = url_line(M, Query_line),
Func = <<<<<<<<<<<<<<<<<<<<<<"pub fn "/utf8,
(base_snake(
Cfg,
erlang:element(
2,
M
)
))/binary>>/binary,
"(\n "/utf8>>/binary,
(gleam@string:join(
Decls,
<<",\n "/utf8>>
))/binary>>/binary,
",\n) -> Result("/utf8>>/binary,
Ret_type@1/binary>>/binary,
", "/utf8>>/binary,
Base_p/binary>>/binary,
"Error) {\n"/utf8>>/binary,
Url_line/binary>>/binary,
Chain/binary>>/binary,
"\n}"/utf8>>,
_pipe@3 = [[error_type(Cfg, M)],
[error_map(Cfg, M)],
Params_defs,
Input_defs,
Output_defs,
[Func]],
_pipe@4 = lists:append(_pipe@3),
_pipe@5 = gleam@string:join(
_pipe@4,
<<"\n\n"/utf8>>
),
{ok, _pipe@5}
end
)
end
)
end
).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 61).
-spec collect_methods(list(atproto_codegen@lower:flat_lexicon())) -> list(atproto_codegen@lower:method()).
collect_methods(Lexicons) ->
_pipe = Lexicons,
_pipe@1 = gleam@list:flat_map(
_pipe,
fun(Lex) ->
gleam@list:filter_map(
erlang:element(4, Lex),
fun(D) ->
gleam@option:to_result(
atproto_codegen@lower:method_of(D),
nil
)
end
)
end
),
gleam@list:sort(
_pipe@1,
fun(A, B) ->
gleam@string:compare(erlang:element(2, A), erlang:element(2, B))
end
).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 45).
-spec emit(atproto_codegen@plugin:plugin_context()) -> {ok,
list(atproto_codegen@plugin:output_file())} |
{error, atproto_codegen@plugin:codegen_error()}.
emit(Ctx) ->
Path = <<(gleam@option:unwrap(
erlang:element(6, erlang:element(2, Ctx)),
<<"client"/utf8>>
))/binary,
".gleam"/utf8>>,
Methods = collect_methods(erlang:element(4, Ctx)),
gleam@result:'try'(
gleam@list:try_map(
Methods,
fun(_capture) -> method_block(erlang:element(2, Ctx), _capture) end
),
fun(Blocks) ->
Content = <<<<<<<<<<<<<<"//// Generated by codegen from lexicons/. Do not edit by hand."/utf8,
"\n"/utf8>>/binary,
"//// Typed XRPC client functions for the generated lexicon methods.\n//// Each function takes an `xrpc.Client`, a service base URL, and an auth\n//// token, and returns a typed result or a per-method error union."/utf8>>/binary,
"\n\n"/utf8>>/binary,
(imports(erlang:element(2, Ctx), Methods))/binary>>/binary,
"\n"/utf8>>/binary,
(gleam@string:join(Blocks, <<"\n\n"/utf8>>))/binary>>/binary,
"\n"/utf8>>,
{ok, [{whole_file, Path, Content}]}
end
).
-file("src/atproto_codegen/plugins/xrpc_client.gleam", 41).
-spec plugin() -> atproto_codegen@plugin:plugin().
plugin() ->
{plugin,
<<"xrpc-client"/utf8>>,
[<<"types"/utf8>>, <<"decode-json"/utf8>>],
fun emit/1}.