Packages
oaspec
0.56.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.1
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.3
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.1.3
Generate Gleam code from OpenAPI 3.x specifications
Current section
Files
Jump to
Current section
Files
src/oaspec@internal@codegen@decoders.erl
-module(oaspec@internal@codegen@decoders).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/internal/codegen/decoders.gleam").
-export([generate/1]).
-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).
-file("src/oaspec/internal/codegen/decoders.gleam", 278).
?DOC(false).
-spec collect_operation_inline_schemas(
list({binary(),
oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()),
binary(),
oaspec@internal@openapi@spec:http_method()})
) -> list(oaspec@internal@openapi@schema:schema_ref()).
collect_operation_inline_schemas(Operations) ->
gleam@list:flat_map(
Operations,
fun(Op) ->
{_, Operation, _, _} = Op,
Response_schemas = gleam@list:flat_map(
maps:to_list(erlang:element(8, Operation)),
fun(Entry) ->
{_, Ref_or_response} = Entry,
case Ref_or_response of
{value, Response} ->
gleam@list:filter_map(
maps:to_list(erlang:element(3, Response)),
fun(Content_entry) ->
{_, Media_type} = Content_entry,
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
{ok, {inline, Schema_obj}};
_ ->
{error, nil}
end
end
);
{ref, _} ->
[]
end
end
),
Request_schemas = case erlang:element(7, Operation) of
{some, {value, Rb}} ->
gleam@list:filter_map(
maps:to_list(erlang:element(3, Rb)),
fun(Content_entry@1) ->
{_, Media_type@1} = Content_entry@1,
case erlang:element(2, Media_type@1) of
{some, {inline, Schema_obj@1}} ->
{ok, {inline, Schema_obj@1}};
_ ->
{error, nil}
end
end
);
_ ->
[]
end,
lists:append(Response_schemas, Request_schemas)
end
).
-file("src/oaspec/internal/codegen/decoders.gleam", 973).
?DOC(false).
-spec generate_primitive_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
binary()
) -> gleam@string_tree:string_tree().
generate_primitive_decoder(
Sb,
Fn_name,
Decoder_fn_name,
Gleam_type,
Decoder_expr
) ->
_pipe = Sb,
_pipe@1 = oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder("/utf8>>/binary,
Gleam_type/binary>>/binary,
") {"/utf8>>
),
_pipe@2 = oaspec@internal@util@string_extra:indent(_pipe@1, 1, Decoder_expr),
_pipe@3 = oaspec@internal@util@string_extra:line(_pipe@2, <<"}"/utf8>>),
_pipe@4 = oaspec@internal@util@string_extra:blank_line(_pipe@3),
_pipe@5 = oaspec@internal@util@string_extra:line(
_pipe@4,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result("/utf8>>/binary,
Gleam_type/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@6 = oaspec@internal@util@string_extra:indent(
_pipe@5,
1,
<<<<"json.parse(json_string, "/utf8, Decoder_expr/binary>>/binary,
")"/utf8>>
),
_pipe@7 = oaspec@internal@util@string_extra:line(_pipe@6, <<"}"/utf8>>),
oaspec@internal@util@string_extra:blank_line(_pipe@7).
-file("src/oaspec/internal/codegen/decoders.gleam", 1354).
?DOC(false).
-spec get_discriminator_value(
oaspec@internal@openapi@schema:discriminator(),
binary(),
binary()
) -> binary().
get_discriminator_value(Disc, Ref, Ref_name) ->
Found = begin
_pipe = maps:to_list(erlang:element(3, Disc)),
gleam@list:find(
_pipe,
fun(Entry) ->
{_, Target} = Entry,
(Target =:= Ref) orelse (oaspec@internal@openapi@resolver:ref_to_name(
Target
)
=:= Ref_name)
end
)
end,
case Found of
{ok, {Disc_value, _}} ->
Disc_value;
{error, _} ->
Ref_name
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 1378).
?DOC(false).
-spec schema_ref_to_decoder(
oaspec@internal@openapi@schema:schema_ref(),
binary(),
binary(),
oaspec@internal@codegen@context:context()
) -> binary().
schema_ref_to_decoder(Ref, Parent_name, Prop_name, Ctx) ->
case Ref of
{inline, {string_schema, _, _, Enum_values, _, _, _}} when Enum_values =/= [] ->
Decoder_name = oaspec@internal@util@naming:to_snake_case(
oaspec@internal@codegen@ir_build:inline_enum_type_name_for(
Parent_name,
Prop_name,
Ctx
)
),
<<Decoder_name/binary, "_decoder()"/utf8>>;
{inline, {array_schema, _, Items, _, _, _}} ->
Inner = schema_ref_to_decoder(Items, Parent_name, Prop_name, Ctx),
<<<<"decode.list("/utf8, Inner/binary>>/binary, ")"/utf8>>;
_ ->
oaspec@internal@codegen@schema_dispatch:decoder_expr(Ref)
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 1011).
?DOC(false).
-spec generate_array_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
oaspec@internal@openapi@schema:schema_ref(),
boolean(),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_array_decoder(Sb, Name, Fn_name, Decoder_fn_name, Items, Nullable, Ctx) ->
Inner_decoder = schema_ref_to_decoder(Items, Name, <<""/utf8>>, Ctx),
Inner_type = oaspec@internal@codegen@codec_helpers:qualified_schema_ref_type(
Items,
Ctx
),
List_type = <<<<"List("/utf8, Inner_type/binary>>/binary, ")"/utf8>>,
List_decoder = <<<<"decode.list("/utf8, Inner_decoder/binary>>/binary,
")"/utf8>>,
{Gleam_type, Decoder_expr} = case Nullable of
true ->
{<<<<"Option("/utf8, List_type/binary>>/binary, ")"/utf8>>,
<<<<"decode.optional("/utf8, List_decoder/binary>>/binary,
")"/utf8>>};
false ->
{List_type, List_decoder}
end,
_pipe = Sb,
_pipe@1 = oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder("/utf8>>/binary,
Gleam_type/binary>>/binary,
") {"/utf8>>
),
_pipe@2 = oaspec@internal@util@string_extra:indent(_pipe@1, 1, Decoder_expr),
_pipe@3 = oaspec@internal@util@string_extra:line(_pipe@2, <<"}"/utf8>>),
_pipe@4 = oaspec@internal@util@string_extra:blank_line(_pipe@3),
_pipe@5 = oaspec@internal@util@string_extra:line(
_pipe@4,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result("/utf8>>/binary,
Gleam_type/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@6 = oaspec@internal@util@string_extra:indent(
_pipe@5,
1,
<<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@7 = oaspec@internal@util@string_extra:line(_pipe@6, <<"}"/utf8>>),
oaspec@internal@util@string_extra:blank_line(_pipe@7).
-file("src/oaspec/internal/codegen/decoders.gleam", 1407).
?DOC(false).
-spec synthetic_list_suffix_for(
binary(),
oaspec@internal@codegen@context:context()
) -> binary().
synthetic_list_suffix_for(Base, Ctx) ->
Schema_names = case erlang:element(
5,
oaspec@internal@codegen@context:spec(Ctx)
) of
{some, Components} ->
_pipe = erlang:element(2, Components),
maps:keys(_pipe);
none ->
[]
end,
oaspec@internal@util@naming:synthetic_list_suffix(Base, Schema_names).
-file("src/oaspec/internal/codegen/decoders.gleam", 1416).
?DOC(false).
-spec maybe_doc_comment(
gleam@string_tree:string_tree(),
gleam@option:option(binary())
) -> gleam@string_tree:string_tree().
maybe_doc_comment(Sb, Description) ->
case Description of
{some, Desc} ->
_pipe = Sb,
oaspec@internal@util@string_extra:doc_comment(_pipe, Desc);
none ->
Sb
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 818).
?DOC(false).
-spec generate_enum_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
list(binary())
) -> gleam@string_tree:string_tree().
generate_enum_decoder(
Sb,
Type_name,
Fn_name,
Decoder_fn_name,
Description,
Enum_values
) ->
Sb@1 = maybe_doc_comment(Sb, Description),
Sb@2 = begin
_pipe = Sb@1,
_pipe@1 = oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
),
_pipe@2 = oaspec@internal@util@string_extra:indent(
_pipe@1,
1,
<<"use value <- decode.then(decode.string)"/utf8>>
),
oaspec@internal@util@string_extra:indent(
_pipe@2,
1,
<<"case value {"/utf8>>
)
end,
Deduped_variants = oaspec@internal@openapi@dedup:dedup_enum_variants(
Enum_values
),
Sb@4 = gleam@list:index_fold(
Enum_values,
Sb@2,
fun(Sb@3, Value, Idx) ->
Variant_suffix = oaspec@internal@codegen@codec_helpers:list_at_or(
Deduped_variants,
Idx,
oaspec@internal@util@naming:to_pascal_case(Value)
),
Variant = <<(oaspec@internal@util@naming:schema_to_type_name(
Type_name
))/binary,
Variant_suffix/binary>>,
_pipe@3 = Sb@3,
oaspec@internal@util@string_extra:indent(
_pipe@3,
2,
<<<<<<<<"\""/utf8, Value/binary>>/binary,
"\" -> decode.success(types."/utf8>>/binary,
Variant/binary>>/binary,
")"/utf8>>
)
end
),
First_variant_suffix = oaspec@internal@codegen@codec_helpers:list_at_or(
Deduped_variants,
0,
case Enum_values of
[First | _] ->
oaspec@internal@util@naming:to_pascal_case(First);
[] ->
<<"Unknown"/utf8>>
end
),
_pipe@4 = Sb@4,
_pipe@5 = oaspec@internal@util@string_extra:indent(
_pipe@4,
2,
<<<<<<<<<<"_ -> decode.failure(types."/utf8,
(oaspec@internal@util@naming:schema_to_type_name(
Type_name
))/binary>>/binary,
First_variant_suffix/binary>>/binary,
", \""/utf8>>/binary,
Type_name/binary>>/binary,
": unknown variant \" <> value)"/utf8>>
),
_pipe@6 = oaspec@internal@util@string_extra:indent(_pipe@5, 1, <<"}"/utf8>>),
_pipe@7 = oaspec@internal@util@string_extra:line(_pipe@6, <<"}"/utf8>>),
_pipe@8 = oaspec@internal@util@string_extra:blank_line(_pipe@7),
_pipe@9 = oaspec@internal@util@string_extra:line(
_pipe@8,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@10 = oaspec@internal@util@string_extra:indent(
_pipe@9,
1,
<<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@11 = oaspec@internal@util@string_extra:line(_pipe@10, <<"}"/utf8>>),
oaspec@internal@util@string_extra:blank_line(_pipe@11).
-file("src/oaspec/internal/codegen/decoders.gleam", 889).
?DOC(false).
-spec generate_anyof_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
list(oaspec@internal@openapi@schema:schema_ref())
) -> gleam@string_tree:string_tree().
generate_anyof_decoder(
Sb,
Type_name,
Fn_name,
Decoder_fn_name,
Description,
Schemas
) ->
Sb@1 = maybe_doc_comment(Sb, Description),
Variant_fields = gleam@list:map(Schemas, fun(S_ref) -> case S_ref of
{reference, _, Ref_name} ->
Field_name = oaspec@internal@util@naming:to_snake_case(
Ref_name
),
Decoder_name = <<(oaspec@internal@util@naming:to_snake_case(
Ref_name
))/binary,
"_decoder"/utf8>>,
{Field_name, Decoder_name, Ref_name};
{inline, _} ->
{<<"unknown"/utf8>>,
<<"decode.string"/utf8>>,
<<"Unknown"/utf8>>}
end end),
Sb@2 = begin
_pipe = Sb@1,
oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
)
end,
Sb@4 = gleam@list:fold(
Variant_fields,
Sb@2,
fun(Sb@3, Field) ->
{Field_name@1, Decoder_name@1, _} = Field,
_pipe@1 = Sb@3,
oaspec@internal@util@string_extra:indent(
_pipe@1,
1,
<<<<<<<<"use "/utf8, Field_name@1/binary>>/binary,
" <- decode.then(decode.one_of("/utf8>>/binary,
Decoder_name@1/binary>>/binary,
"() |> decode.map(option.Some), or: [decode.success(option.None)]))"/utf8>>
)
end
),
Field_assignments = gleam@list:map(
Variant_fields,
fun(F) ->
{Field_name@2, _, _} = F,
<<<<Field_name@2/binary, ": "/utf8>>/binary, Field_name@2/binary>>
end
),
_pipe@2 = Sb@4,
_pipe@3 = oaspec@internal@util@string_extra:indent(
_pipe@2,
1,
<<<<<<<<"decode.success(types."/utf8, Type_name/binary>>/binary,
"("/utf8>>/binary,
(gleam@string:join(Field_assignments, <<", "/utf8>>))/binary>>/binary,
"))"/utf8>>
),
_pipe@4 = oaspec@internal@util@string_extra:line(_pipe@3, <<"}"/utf8>>),
_pipe@5 = oaspec@internal@util@string_extra:blank_line(_pipe@4),
_pipe@6 = oaspec@internal@util@string_extra:line(
_pipe@5,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@7 = oaspec@internal@util@string_extra:indent(
_pipe@6,
1,
<<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@8 = oaspec@internal@util@string_extra:line(_pipe@7, <<"}"/utf8>>),
oaspec@internal@util@string_extra:blank_line(_pipe@8).
-file("src/oaspec/internal/codegen/decoders.gleam", 1057).
?DOC(false).
-spec generate_oneof_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
list(oaspec@internal@openapi@schema:schema_ref()),
gleam@option:option(oaspec@internal@openapi@schema:discriminator()),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_oneof_decoder(
Sb,
_,
Type_name,
Fn_name,
Decoder_fn_name,
Description,
Schemas,
Discriminator,
_
) ->
All_refs = gleam@list:all(Schemas, fun(S) -> case S of
{reference, _, _} ->
true;
_ ->
false
end end),
case All_refs of
false ->
Sb;
true ->
Sb@1 = maybe_doc_comment(Sb, Description),
case Discriminator of
{some, Disc} ->
Sb@2 = begin
_pipe = Sb@1,
_pipe@1 = oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
),
_pipe@2 = oaspec@internal@util@string_extra:indent(
_pipe@1,
1,
<<<<"use disc_value <- decode.field(\""/utf8,
(erlang:element(2, Disc))/binary>>/binary,
"\", decode.string)"/utf8>>
),
oaspec@internal@util@string_extra:indent(
_pipe@2,
1,
<<"case disc_value {"/utf8>>
)
end,
Sb@4 = gleam@list:fold(
Schemas,
Sb@2,
fun(Sb@3, S_ref) -> case S_ref of
{reference, Ref, Name} ->
Ref_name = Name,
Variant_type = oaspec@internal@util@naming:schema_to_type_name(
Ref_name
),
Variant_name = <<Type_name/binary,
Variant_type/binary>>,
Variant_decoder = <<(oaspec@internal@util@naming:to_snake_case(
Ref_name
))/binary,
"_decoder()"/utf8>>,
Disc_value = get_discriminator_value(
Disc,
Ref,
Ref_name
),
_pipe@3 = Sb@3,
_pipe@4 = oaspec@internal@util@string_extra:indent(
_pipe@3,
2,
<<<<"\""/utf8, Disc_value/binary>>/binary,
"\" -> {"/utf8>>
),
_pipe@5 = oaspec@internal@util@string_extra:indent(
_pipe@4,
3,
<<<<"use inner <- decode.then("/utf8,
Variant_decoder/binary>>/binary,
")"/utf8>>
),
_pipe@6 = oaspec@internal@util@string_extra:indent(
_pipe@5,
3,
<<<<"decode.success(types."/utf8,
Variant_name/binary>>/binary,
"(inner))"/utf8>>
),
oaspec@internal@util@string_extra:indent(
_pipe@6,
2,
<<"}"/utf8>>
);
_ ->
Sb@3
end end
),
First_ref_decoder = case Schemas of
[{reference, _, Name@1} | _] ->
Ref_name@1 = Name@1,
<<(oaspec@internal@util@naming:to_snake_case(
Ref_name@1
))/binary,
"_decoder()"/utf8>>;
_ ->
<<"decode.string"/utf8>>
end,
First_variant_name = case Schemas of
[{reference, _, Name@2} | _] ->
Ref_name@2 = Name@2,
Variant_type@1 = oaspec@internal@util@naming:schema_to_type_name(
Ref_name@2
),
<<<<"types."/utf8, Type_name/binary>>/binary,
Variant_type@1/binary>>;
_ ->
<<"types."/utf8, Type_name/binary>>
end,
Valid_disc_values = begin
_pipe@7 = Schemas,
_pipe@8 = gleam@list:filter_map(
_pipe@7,
fun(S_ref@1) -> case S_ref@1 of
{reference, Ref@1, Name@3} ->
{ok,
get_discriminator_value(
Disc,
Ref@1,
Name@3
)};
_ ->
{error, nil}
end end
),
_pipe@9 = gleam@list:sort(
_pipe@8,
fun gleam@string:compare/2
),
gleam@string:join(_pipe@9, <<"|"/utf8>>)
end,
Sb@5 = begin
_pipe@10 = Sb@4,
_pipe@11 = oaspec@internal@util@string_extra:indent(
_pipe@10,
2,
<<"_ -> {"/utf8>>
),
_pipe@12 = oaspec@internal@util@string_extra:indent(
_pipe@11,
3,
<<<<<<<<"use _ <- decode.then(decode.failure(Nil, \""/utf8,
Type_name/binary>>/binary,
": unknown discriminator '\" <> disc_value <> \"' (expected "/utf8>>/binary,
Valid_disc_values/binary>>/binary,
")\"))"/utf8>>
),
_pipe@13 = oaspec@internal@util@string_extra:indent(
_pipe@12,
3,
<<<<"use v <- decode.then("/utf8,
First_ref_decoder/binary>>/binary,
")"/utf8>>
),
_pipe@14 = oaspec@internal@util@string_extra:indent(
_pipe@13,
3,
<<<<<<<<"decode.failure("/utf8,
First_variant_name/binary>>/binary,
"(v), \""/utf8>>/binary,
Type_name/binary>>/binary,
"\")"/utf8>>
),
_pipe@15 = oaspec@internal@util@string_extra:indent(
_pipe@14,
2,
<<"}"/utf8>>
),
_pipe@16 = oaspec@internal@util@string_extra:indent(
_pipe@15,
1,
<<"}"/utf8>>
),
_pipe@17 = oaspec@internal@util@string_extra:line(
_pipe@16,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@17)
end,
_pipe@18 = Sb@5,
_pipe@19 = oaspec@internal@util@string_extra:line(
_pipe@18,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@20 = oaspec@internal@util@string_extra:indent(
_pipe@19,
1,
<<<<"json.parse(json_string, "/utf8,
Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@21 = oaspec@internal@util@string_extra:line(
_pipe@20,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@21);
none ->
Ref_variants = gleam@list:filter_map(
Schemas,
fun(S_ref@2) -> case S_ref@2 of
{reference, _, Name@4} ->
Ref_name@3 = Name@4,
{ok, Ref_name@3};
_ ->
{error, nil}
end end
),
Sb@6 = begin
_pipe@22 = Sb@1,
oaspec@internal@util@string_extra:line(
_pipe@22,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
)
end,
Sb@10 = case Ref_variants of
[] ->
_pipe@23 = Sb@6,
oaspec@internal@util@string_extra:indent(
_pipe@23,
1,
<<<<<<<<"decode.failure(types."/utf8,
Type_name/binary>>/binary,
", \""/utf8>>/binary,
Type_name/binary>>/binary,
"\")"/utf8>>
);
[First | _] ->
First_variant_type = oaspec@internal@util@naming:schema_to_type_name(
First
),
First_decoder = <<(oaspec@internal@util@naming:to_snake_case(
First
))/binary,
"_decoder()"/utf8>>,
Sb@7 = begin
_pipe@24 = Sb@6,
oaspec@internal@util@string_extra:indent(
_pipe@24,
1,
<<"use raw <- decode.then(decode.dynamic)"/utf8>>
)
end,
Sb@9 = gleam@list:index_fold(
Ref_variants,
Sb@7,
fun(Sb@8, Ref_name@4, Idx) ->
Variant_type@2 = oaspec@internal@util@naming:schema_to_type_name(
Ref_name@4
),
Decoder = <<(oaspec@internal@util@naming:to_snake_case(
Ref_name@4
))/binary,
"_decoder()"/utf8>>,
_pipe@25 = Sb@8,
oaspec@internal@util@string_extra:indent(
_pipe@25,
1,
<<<<<<<<<<<<<<"let r"/utf8,
(erlang:integer_to_binary(
Idx
))/binary>>/binary,
" = decode.run(raw, "/utf8>>/binary,
Decoder/binary>>/binary,
") |> result.map(types."/utf8>>/binary,
Type_name/binary>>/binary,
Variant_type@2/binary>>/binary,
")"/utf8>>
)
end
),
Attempts_list = <<<<"["/utf8,
(oaspec@internal@util@string_extra:join_with(
gleam@list:index_map(
Ref_variants,
fun(_, Idx@1) ->
<<"r"/utf8,
(erlang:integer_to_binary(
Idx@1
))/binary>>
end
),
<<", "/utf8>>
))/binary>>/binary,
"]"/utf8>>,
_pipe@26 = Sb@9,
_pipe@27 = oaspec@internal@util@string_extra:indent(
_pipe@26,
1,
<<<<"let oks = list.filter_map("/utf8,
Attempts_list/binary>>/binary,
", fn(r) {"/utf8>>
),
_pipe@28 = oaspec@internal@util@string_extra:indent(
_pipe@27,
2,
<<"case r {"/utf8>>
),
_pipe@29 = oaspec@internal@util@string_extra:indent(
_pipe@28,
3,
<<"Ok(v) -> Ok(v)"/utf8>>
),
_pipe@30 = oaspec@internal@util@string_extra:indent(
_pipe@29,
3,
<<"Error(_) -> Error(Nil)"/utf8>>
),
_pipe@31 = oaspec@internal@util@string_extra:indent(
_pipe@30,
2,
<<"}"/utf8>>
),
_pipe@32 = oaspec@internal@util@string_extra:indent(
_pipe@31,
1,
<<"})"/utf8>>
),
_pipe@33 = oaspec@internal@util@string_extra:indent(
_pipe@32,
1,
<<"case oks {"/utf8>>
),
_pipe@34 = oaspec@internal@util@string_extra:indent(
_pipe@33,
2,
<<"[single] -> decode.success(single)"/utf8>>
),
_pipe@35 = oaspec@internal@util@string_extra:indent(
_pipe@34,
2,
<<<<"[first, _, ..] -> decode.failure(first, \""/utf8,
Type_name/binary>>/binary,
": matched multiple oneOf branches; expected exactly one\")"/utf8>>
),
_pipe@36 = oaspec@internal@util@string_extra:indent(
_pipe@35,
2,
<<"[] -> {"/utf8>>
),
_pipe@37 = oaspec@internal@util@string_extra:indent(
_pipe@36,
3,
<<<<"use fallback <- decode.then("/utf8,
First_decoder/binary>>/binary,
")"/utf8>>
),
_pipe@38 = oaspec@internal@util@string_extra:indent(
_pipe@37,
3,
<<<<<<<<<<"decode.failure(types."/utf8,
Type_name/binary>>/binary,
First_variant_type/binary>>/binary,
"(fallback), \""/utf8>>/binary,
Type_name/binary>>/binary,
": no oneOf branch matched\")"/utf8>>
),
_pipe@39 = oaspec@internal@util@string_extra:indent(
_pipe@38,
2,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:indent(
_pipe@39,
1,
<<"}"/utf8>>
)
end,
Sb@11 = begin
_pipe@40 = Sb@10,
_pipe@41 = oaspec@internal@util@string_extra:line(
_pipe@40,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@41)
end,
_pipe@42 = Sb@11,
_pipe@43 = oaspec@internal@util@string_extra:line(
_pipe@42,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@44 = oaspec@internal@util@string_extra:indent(
_pipe@43,
1,
<<<<"json.parse(json_string, "/utf8,
Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@45 = oaspec@internal@util@string_extra:line(
_pipe@44,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@45)
end
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 1435).
?DOC(false).
-spec emit_constant_field_decoder(
gleam@string_tree:string_tree(),
binary(),
binary()
) -> gleam@string_tree:string_tree().
emit_constant_field_decoder(Sb, Prop_name, Constant_value) ->
Escaped = oaspec@internal@codegen@codec_helpers:escape_for_string_literal(
Constant_value
),
_pipe = Sb,
_pipe@1 = oaspec@internal@util@string_extra:indent(
_pipe,
1,
<<<<"use _ <- decode.field(\""/utf8, Prop_name/binary>>/binary,
"\", decode.then(decode.string, fn(constant_value) {"/utf8>>
),
_pipe@2 = oaspec@internal@util@string_extra:indent(
_pipe@1,
2,
<<"case constant_value {"/utf8>>
),
_pipe@3 = oaspec@internal@util@string_extra:indent(
_pipe@2,
3,
<<<<"\""/utf8, Escaped/binary>>/binary,
"\" -> decode.success(Nil)"/utf8>>
),
_pipe@4 = oaspec@internal@util@string_extra:indent(
_pipe@3,
3,
<<<<<<<<"other -> decode.failure(Nil, \"expected "/utf8,
Prop_name/binary>>/binary,
"=\\\""/utf8>>/binary,
Escaped/binary>>/binary,
"\\\", got \\\"\" <> other <> \"\\\"\")"/utf8>>
),
_pipe@5 = oaspec@internal@util@string_extra:indent(_pipe@4, 2, <<"}"/utf8>>),
oaspec@internal@util@string_extra:indent(_pipe@5, 1, <<"}))"/utf8>>).
-file("src/oaspec/internal/codegen/decoders.gleam", 517).
?DOC(false).
-spec generate_object_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
gleam@dict:dict(binary(), oaspec@internal@openapi@schema:schema_ref()),
list(binary()),
oaspec@internal@openapi@schema:additional_properties(),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_object_decoder(
Sb,
Name,
Type_name,
Fn_name,
Decoder_fn_name,
Description,
Properties,
Required,
Additional_properties,
Ctx
) ->
Sb@1 = maybe_doc_comment(Sb, Description),
Sb@2 = begin
_pipe = Sb@1,
oaspec@internal@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
)
end,
Props = oaspec@internal@codegen@ir_build:sorted_entries(Properties),
Deduped_names = oaspec@internal@openapi@dedup:dedup_property_names(
gleam@list:map(Props, fun(E) -> erlang:element(1, E) end)
),
Sb@4 = gleam@list:index_fold(
Props,
Sb@2,
fun(Sb@3, Entry, Idx) ->
{Prop_name, Prop_ref} = Entry,
Field_name = oaspec@internal@codegen@codec_helpers:list_at_or(
Deduped_names,
Idx,
oaspec@internal@util@naming:to_snake_case(Prop_name)
),
Is_write_only = oaspec@internal@codegen@schema_utils:schema_ref_is_write_only(
Prop_ref,
Ctx
),
Is_required = gleam@list:contains(Required, Prop_name) andalso not Is_write_only,
Field_decoder = schema_ref_to_decoder(
Prop_ref,
Name,
Prop_name,
Ctx
),
Is_nullable_schema = oaspec@internal@codegen@schema_utils:schema_ref_is_nullable(
Prop_ref,
Ctx
),
Effective_decoder = case Is_nullable_schema of
true ->
<<<<"decode.optional("/utf8, Field_decoder/binary>>/binary,
")"/utf8>>;
false ->
Field_decoder
end,
case oaspec@internal@codegen@schema_utils:constant_property_value(
Prop_ref,
Prop_name,
Required
) of
{some, Constant_value} ->
_pipe@1 = Sb@3,
emit_constant_field_decoder(
_pipe@1,
Prop_name,
Constant_value
);
none ->
case Is_required of
true ->
_pipe@2 = Sb@3,
oaspec@internal@util@string_extra:indent(
_pipe@2,
1,
<<<<<<<<<<<<"use "/utf8, Field_name/binary>>/binary,
" <- decode.field(\""/utf8>>/binary,
Prop_name/binary>>/binary,
"\", "/utf8>>/binary,
Effective_decoder/binary>>/binary,
")"/utf8>>
);
false ->
case Is_nullable_schema of
true ->
_pipe@3 = Sb@3,
oaspec@internal@util@string_extra:indent(
_pipe@3,
1,
<<<<<<<<<<<<"use "/utf8,
Field_name/binary>>/binary,
" <- decode.optional_field(\""/utf8>>/binary,
Prop_name/binary>>/binary,
"\", option.None, "/utf8>>/binary,
Effective_decoder/binary>>/binary,
")"/utf8>>
);
false ->
_pipe@4 = Sb@3,
oaspec@internal@util@string_extra:indent(
_pipe@4,
1,
<<<<<<<<<<<<"use "/utf8,
Field_name/binary>>/binary,
" <- decode.optional_field(\""/utf8>>/binary,
Prop_name/binary>>/binary,
"\", option.None, decode.optional("/utf8>>/binary,
Field_decoder/binary>>/binary,
"))"/utf8>>
)
end
end
end
end
),
Known_keys_expr = case gleam@list:is_empty(Props) of
true ->
<<"[]"/utf8>>;
false ->
<<<<"["/utf8,
(oaspec@internal@util@string_extra:join_with(
gleam@list:map(
Props,
fun(Entry@1) ->
{Prop_name@1, _} = Entry@1,
<<<<"\""/utf8, Prop_name@1/binary>>/binary,
"\""/utf8>>
end
),
<<", "/utf8>>
))/binary>>/binary,
"]"/utf8>>
end,
Sb@5 = case Additional_properties of
{typed, Ap_ref} ->
Inner_decoder = schema_ref_to_decoder(
Ap_ref,
Name,
<<"additional_properties"/utf8>>,
Ctx
),
_pipe@5 = Sb@4,
_pipe@6 = oaspec@internal@util@string_extra:indent(
_pipe@5,
1,
<<"use all_props <- decode.then(decode.dict(decode.string, decode.new_primitive_decoder(\"Dynamic\", fn(x) { Ok(x) })))"/utf8>>
),
_pipe@7 = oaspec@internal@util@string_extra:indent(
_pipe@6,
1,
<<<<"let extra_props = dict.drop(all_props, "/utf8,
Known_keys_expr/binary>>/binary,
")"/utf8>>
),
_pipe@8 = oaspec@internal@util@string_extra:indent(
_pipe@7,
1,
<<"let additional_properties_result = dict.fold(extra_props, Ok(dict.new()), fn(acc, k, v) {"/utf8>>
),
_pipe@9 = oaspec@internal@util@string_extra:indent(
_pipe@8,
2,
<<"case acc {"/utf8>>
),
_pipe@10 = oaspec@internal@util@string_extra:indent(
_pipe@9,
3,
<<"Ok(decoded_acc) ->"/utf8>>
),
_pipe@11 = oaspec@internal@util@string_extra:indent(
_pipe@10,
4,
<<<<"case decode.run(v, "/utf8, Inner_decoder/binary>>/binary,
") {"/utf8>>
),
_pipe@12 = oaspec@internal@util@string_extra:indent(
_pipe@11,
5,
<<"Ok(decoded) -> Ok(dict.insert(decoded_acc, k, decoded))"/utf8>>
),
_pipe@13 = oaspec@internal@util@string_extra:indent(
_pipe@12,
5,
<<"Error(_) -> Error(Nil)"/utf8>>
),
_pipe@14 = oaspec@internal@util@string_extra:indent(
_pipe@13,
4,
<<"}"/utf8>>
),
_pipe@15 = oaspec@internal@util@string_extra:indent(
_pipe@14,
3,
<<"Error(_) -> Error(Nil)"/utf8>>
),
_pipe@16 = oaspec@internal@util@string_extra:indent(
_pipe@15,
2,
<<"}"/utf8>>
),
_pipe@17 = oaspec@internal@util@string_extra:indent(
_pipe@16,
1,
<<"})"/utf8>>
),
_pipe@18 = oaspec@internal@util@string_extra:indent(
_pipe@17,
1,
<<"use additional_properties <- decode.then(case additional_properties_result {"/utf8>>
),
_pipe@19 = oaspec@internal@util@string_extra:indent(
_pipe@18,
2,
<<"Ok(decoded) -> decode.success(decoded)"/utf8>>
),
_pipe@20 = oaspec@internal@util@string_extra:indent(
_pipe@19,
2,
<<"Error(_) -> decode.failure(dict.new(), \"additionalProperties\")"/utf8>>
),
oaspec@internal@util@string_extra:indent(_pipe@20, 1, <<"})"/utf8>>);
untyped ->
_pipe@21 = Sb@4,
_pipe@22 = oaspec@internal@util@string_extra:indent(
_pipe@21,
1,
<<"use all_props <- decode.then(decode.dict(decode.string, decode.new_primitive_decoder(\"Dynamic\", fn(x) { Ok(x) })))"/utf8>>
),
oaspec@internal@util@string_extra:indent(
_pipe@22,
1,
<<<<"let additional_properties = dict.drop(all_props, "/utf8,
Known_keys_expr/binary>>/binary,
")"/utf8>>
);
forbidden ->
_pipe@23 = Sb@4,
_pipe@24 = oaspec@internal@util@string_extra:indent(
_pipe@23,
1,
<<"use all_props <- decode.then(decode.dict(decode.string, decode.new_primitive_decoder(\"Dynamic\", fn(x) { Ok(x) })))"/utf8>>
),
_pipe@25 = oaspec@internal@util@string_extra:indent(
_pipe@24,
1,
<<<<"let extra_props = dict.drop(all_props, "/utf8,
Known_keys_expr/binary>>/binary,
")"/utf8>>
),
_pipe@26 = oaspec@internal@util@string_extra:indent(
_pipe@25,
1,
<<"use _ <- decode.then(case dict.is_empty(extra_props) {"/utf8>>
),
_pipe@27 = oaspec@internal@util@string_extra:indent(
_pipe@26,
2,
<<"True -> decode.success(Nil)"/utf8>>
),
_pipe@28 = oaspec@internal@util@string_extra:indent(
_pipe@27,
2,
<<"False -> decode.failure(Nil, \"additionalProperties\")"/utf8>>
),
oaspec@internal@util@string_extra:indent(_pipe@28, 1, <<"})"/utf8>>);
unspecified ->
Sb@4
end,
Param_names = begin
_pipe@29 = gleam@list:index_map(
Props,
fun(Entry@2, Idx@1) ->
{Prop_name@2, Prop_ref@1} = Entry@2,
Field_name@1 = oaspec@internal@codegen@codec_helpers:list_at_or(
Deduped_names,
Idx@1,
oaspec@internal@util@naming:to_snake_case(Prop_name@2)
),
{Prop_name@2, Prop_ref@1, Field_name@1}
end
),
_pipe@30 = gleam@list:filter(
_pipe@29,
fun(Entry@3) ->
{Prop_name@3, Prop_ref@2, _} = Entry@3,
gleam@option:is_none(
oaspec@internal@codegen@schema_utils:constant_property_value(
Prop_ref@2,
Prop_name@3,
Required
)
)
end
),
gleam@list:map(
_pipe@30,
fun(Entry@4) ->
{_, _, Field_name@2} = Entry@4,
<<<<Field_name@2/binary, ": "/utf8>>/binary,
Field_name@2/binary>>
end
)
end,
Param_names@1 = case Additional_properties of
{typed, _} ->
lists:append(
Param_names,
[<<"additional_properties: additional_properties"/utf8>>]
);
untyped ->
lists:append(
Param_names,
[<<"additional_properties: additional_properties"/utf8>>]
);
forbidden ->
Param_names;
unspecified ->
Param_names
end,
Constructor_call = case gleam@list:is_empty(Param_names@1) of
true ->
<<<<"decode.success(types."/utf8, Type_name/binary>>/binary,
")"/utf8>>;
false ->
<<<<<<<<"decode.success(types."/utf8, Type_name/binary>>/binary,
"("/utf8>>/binary,
(oaspec@internal@util@string_extra:join_with(
Param_names@1,
<<", "/utf8>>
))/binary>>/binary,
"))"/utf8>>
end,
Sb@6 = begin
_pipe@31 = Sb@5,
oaspec@internal@util@string_extra:indent(_pipe@31, 1, Constructor_call)
end,
Sb@7 = begin
_pipe@32 = Sb@6,
_pipe@33 = oaspec@internal@util@string_extra:line(
_pipe@32,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@33)
end,
Sb@8 = begin
_pipe@34 = Sb@7,
_pipe@35 = oaspec@internal@util@string_extra:line(
_pipe@34,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@36 = oaspec@internal@util@string_extra:indent(
_pipe@35,
1,
<<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@37 = oaspec@internal@util@string_extra:line(
_pipe@36,
<<"}"/utf8>>
),
oaspec@internal@util@string_extra:blank_line(_pipe@37)
end,
Suffix = synthetic_list_suffix_for(Name, Ctx),
List_fn_name = <<Fn_name/binary, Suffix/binary>>,
List_decoder_fn_name = <<Decoder_fn_name/binary, Suffix/binary>>,
_pipe@38 = Sb@8,
_pipe@39 = oaspec@internal@util@string_extra:line(
_pipe@38,
<<<<<<<<"pub fn "/utf8, List_decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(List(types."/utf8>>/binary,
Type_name/binary>>/binary,
")) {"/utf8>>
),
_pipe@40 = oaspec@internal@util@string_extra:indent(
_pipe@39,
1,
<<<<"decode.list("/utf8, Decoder_fn_name/binary>>/binary, "())"/utf8>>
),
_pipe@41 = oaspec@internal@util@string_extra:line(_pipe@40, <<"}"/utf8>>),
_pipe@42 = oaspec@internal@util@string_extra:blank_line(_pipe@41),
_pipe@43 = oaspec@internal@util@string_extra:line(
_pipe@42,
<<<<<<<<"pub fn "/utf8, List_fn_name/binary>>/binary,
"(json_string: String) -> Result(List(types."/utf8>>/binary,
Type_name/binary>>/binary,
"), json.DecodeError) {"/utf8>>
),
_pipe@44 = oaspec@internal@util@string_extra:indent(
_pipe@43,
1,
<<<<"json.parse(json_string, "/utf8, List_decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@45 = oaspec@internal@util@string_extra:line(_pipe@44, <<"}"/utf8>>),
oaspec@internal@util@string_extra:blank_line(_pipe@45).
-file("src/oaspec/internal/codegen/decoders.gleam", 367).
?DOC(false).
-spec generate_decoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@internal@openapi@schema:schema_ref(),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_decoder(Sb, Name, Schema_ref, Ctx) ->
Type_name = oaspec@internal@util@naming:schema_to_type_name(Name),
Fn_name = <<"decode_"/utf8,
(oaspec@internal@util@naming:to_snake_case(Name))/binary>>,
Decoder_fn_name = <<(oaspec@internal@util@naming:to_snake_case(Name))/binary,
"_decoder"/utf8>>,
case Schema_ref of
{inline,
{object_schema,
Metadata,
Properties,
Required,
Additional_properties,
_,
_}} ->
generate_object_decoder(
Sb,
Name,
Type_name,
Fn_name,
Decoder_fn_name,
erlang:element(2, Metadata),
Properties,
Required,
Additional_properties,
Ctx
);
{inline, {string_schema, Metadata@1, _, Enum_values, _, _, _}} when Enum_values =/= [] ->
generate_enum_decoder(
Sb,
Type_name,
Fn_name,
Decoder_fn_name,
erlang:element(2, Metadata@1),
Enum_values
);
{inline, {all_of_schema, Metadata@2, Schemas}} ->
Merged = oaspec@internal@codegen@allof_merge:merge_allof_schemas(
Schemas,
Ctx
),
Merged_schema = {inline,
{object_schema,
Metadata@2,
erlang:element(2, Merged),
erlang:element(3, Merged),
erlang:element(4, Merged),
none,
none}},
generate_decoder(Sb, Name, Merged_schema, Ctx);
{inline, {one_of_schema, Metadata@3, Schemas@1, Discriminator}} ->
generate_oneof_decoder(
Sb,
Name,
Type_name,
Fn_name,
Decoder_fn_name,
erlang:element(2, Metadata@3),
Schemas@1,
Discriminator,
Ctx
);
{inline, {any_of_schema, Metadata@4, Schemas@2, _}} ->
generate_anyof_decoder(
Sb,
Type_name,
Fn_name,
Decoder_fn_name,
erlang:element(2, Metadata@4),
Schemas@2
);
{inline, {string_schema, Metadata@5, _, [], _, _, _}} ->
{Gleam_type, Decoder_expr} = case erlang:element(3, Metadata@5) of
true ->
{<<"Option(String)"/utf8>>,
<<"decode.optional(decode.string)"/utf8>>};
false ->
{<<"String"/utf8>>, <<"decode.string"/utf8>>}
end,
generate_primitive_decoder(
Sb,
Fn_name,
Decoder_fn_name,
Gleam_type,
Decoder_expr
);
{inline, {integer_schema, Metadata@6, _, _, _, _, _, _}} ->
{Gleam_type@1, Decoder_expr@1} = case erlang:element(3, Metadata@6) of
true ->
{<<"Option(Int)"/utf8>>,
<<"decode.optional(decode.int)"/utf8>>};
false ->
{<<"Int"/utf8>>, <<"decode.int"/utf8>>}
end,
generate_primitive_decoder(
Sb,
Fn_name,
Decoder_fn_name,
Gleam_type@1,
Decoder_expr@1
);
{inline, {number_schema, Metadata@7, _, _, _, _, _, _}} ->
{Gleam_type@2, Decoder_expr@2} = case erlang:element(3, Metadata@7) of
true ->
{<<"Option(Float)"/utf8>>,
<<"decode.optional(decode.float)"/utf8>>};
false ->
{<<"Float"/utf8>>, <<"decode.float"/utf8>>}
end,
generate_primitive_decoder(
Sb,
Fn_name,
Decoder_fn_name,
Gleam_type@2,
Decoder_expr@2
);
{inline, {boolean_schema, Metadata@8}} ->
{Gleam_type@3, Decoder_expr@3} = case erlang:element(3, Metadata@8) of
true ->
{<<"Option(Bool)"/utf8>>,
<<"decode.optional(decode.bool)"/utf8>>};
false ->
{<<"Bool"/utf8>>, <<"decode.bool"/utf8>>}
end,
generate_primitive_decoder(
Sb,
Fn_name,
Decoder_fn_name,
Gleam_type@3,
Decoder_expr@3
);
{inline, {array_schema, Metadata@9, Items, _, _, _}} ->
generate_array_decoder(
Sb,
Name,
Fn_name,
Decoder_fn_name,
Items,
erlang:element(3, Metadata@9),
Ctx
);
_ ->
Sb
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 314).
?DOC(false).
-spec generate_anonymous_schema_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
oaspec@internal@openapi@schema:schema_object(),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_schema_decoder(Sb, Op_id, Suffix, Schema_obj, Ctx) ->
Name = <<<<(oaspec@internal@util@naming:to_snake_case(Op_id))/binary,
"_"/utf8>>/binary,
(oaspec@internal@util@naming:to_snake_case(Suffix))/binary>>,
Schema_ref = {inline, Schema_obj},
generate_decoder(Sb, Name, Schema_ref, Ctx).
-file("src/oaspec/internal/codegen/decoders.gleam", 200).
?DOC(false).
-spec generate_anonymous_response_decoders(
gleam@string_tree:string_tree(),
binary(),
oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_response_decoders(Sb, Op_id, Operation, Ctx) ->
Responses = oaspec@internal@util@http:sort_response_entries(
maps:to_list(erlang:element(8, Operation))
),
gleam@list:fold(
Responses,
Sb,
fun(Sb@1, Entry) ->
{Status_code, Ref_or_response} = Entry,
case Ref_or_response of
{value, Response} ->
Content_entries = oaspec@internal@codegen@ir_build:sorted_entries(
erlang:element(3, Response)
),
case Content_entries of
[{_, Media_type} | _] ->
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
Filtered_schema = oaspec@internal@codegen@schema_utils:filter_write_only_properties(
Schema_obj,
Ctx
),
Suffix = <<"Response"/utf8,
(oaspec@internal@util@http:status_code_suffix(
Status_code
))/binary>>,
generate_anonymous_schema_decoder(
Sb@1,
Op_id,
Suffix,
Filtered_schema,
Ctx
);
_ ->
Sb@1
end;
_ ->
Sb@1
end;
{ref, _} ->
Sb@1
end
end
).
-file("src/oaspec/internal/codegen/decoders.gleam", 239).
?DOC(false).
-spec generate_anonymous_request_body_decoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_request_body_decoder(Sb, Op_id, Operation, Ctx) ->
case erlang:element(7, Operation) of
{some, {value, Rb}} ->
Content_entries = oaspec@internal@codegen@ir_build:sorted_entries(
erlang:element(3, Rb)
),
case Content_entries of
[{_, Media_type} | _] ->
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
Filtered_schema = oaspec@internal@codegen@schema_utils:filter_read_only_properties(
Schema_obj,
Ctx
),
generate_anonymous_schema_decoder(
Sb,
Op_id,
<<"RequestBody"/utf8>>,
Filtered_schema,
Ctx
);
_ ->
Sb
end;
_ ->
Sb
end;
{some, {ref, _}} ->
Sb;
none ->
Sb
end.
-file("src/oaspec/internal/codegen/decoders.gleam", 187).
?DOC(false).
-spec generate_anonymous_decoders(
gleam@string_tree:string_tree(),
oaspec@internal@codegen@context:context(),
list({binary(),
oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()),
binary(),
oaspec@internal@openapi@spec:http_method()})
) -> gleam@string_tree:string_tree().
generate_anonymous_decoders(Sb, Ctx, Operations) ->
gleam@list:fold(
Operations,
Sb,
fun(Sb@1, Op) ->
{Op_id, Operation, _, _} = Op,
Sb@2 = generate_anonymous_response_decoders(
Sb@1,
Op_id,
Operation,
Ctx
),
generate_anonymous_request_body_decoder(Sb@2, Op_id, Operation, Ctx)
end
).
-file("src/oaspec/internal/codegen/decoders.gleam", 327).
?DOC(false).
-spec generate_inline_enum_decoders(
gleam@string_tree:string_tree(),
binary(),
oaspec@internal@openapi@schema:schema_ref(),
oaspec@internal@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_inline_enum_decoders(Sb, Parent_name, Schema_ref, Ctx) ->
{Props, Required@1} = case Schema_ref of
{inline, {object_schema, _, Properties, Required, _, _, _}} ->
{oaspec@internal@codegen@ir_build:sorted_entries(Properties),
Required};
{inline, {all_of_schema, _, Schemas}} ->
Merged = oaspec@internal@codegen@allof_merge:merge_allof_schemas(
Schemas,
Ctx
),
{oaspec@internal@codegen@ir_build:sorted_entries(
erlang:element(2, Merged)
),
erlang:element(3, Merged)};
_ ->
{[], []}
end,
gleam@list:fold(
Props,
Sb,
fun(Sb@1, Entry) ->
{Prop_name, Prop_ref} = Entry,
case oaspec@internal@codegen@schema_utils:constant_property_value(
Prop_ref,
Prop_name,
Required@1
) of
{some, _} ->
Sb@1;
none ->
case Prop_ref of
{inline, {string_schema, _, _, Enum_values, _, _, _}} when Enum_values =/= [] ->
Enum_name = oaspec@internal@codegen@ir_build:inline_enum_type_name_for(
Parent_name,
Prop_name,
Ctx
),
generate_decoder(Sb@1, Enum_name, Prop_ref, Ctx);
_ ->
Sb@1
end
end
end
).
-file("src/oaspec/internal/codegen/decoders.gleam", 50).
?DOC(false).
-spec generate_decoders(
oaspec@internal@codegen@context:context(),
list({binary(),
oaspec@internal@openapi@spec:operation(oaspec@internal@openapi@spec:resolved()),
binary(),
oaspec@internal@openapi@spec:http_method()})
) -> binary().
generate_decoders(Ctx, Operations) ->
Schemas = case erlang:element(5, oaspec@internal@codegen@context:spec(Ctx)) of
{some, Components} ->
_pipe = gleam@list:sort(
maps:to_list(erlang:element(2, Components)),
fun(A, B) ->
gleam@string:compare(
erlang:element(1, A),
erlang:element(1, B)
)
end
),
gleam@list:filter(
_pipe,
fun(Entry) ->
not oaspec@internal@codegen@ir_build:is_internal_schema(
erlang:element(2, Entry)
)
end
);
none ->
[]
end,
Needs_option = gleam@list:any(
Schemas,
fun(Entry@1) ->
{_, Schema_ref} = Entry@1,
oaspec@internal@codegen@schema_utils:schema_has_optional_fields(
Schema_ref,
Ctx
)
end
),
Operation_inline_schemas = collect_operation_inline_schemas(Operations),
Component_needs_dict = gleam@list:any(
Schemas,
fun(Entry@2) ->
{_, Schema_ref@1} = Entry@2,
oaspec@internal@codegen@schema_utils:schema_has_additional_properties(
Schema_ref@1,
Ctx
)
orelse oaspec@internal@codegen@schema_utils:schema_has_forbidden_additional_properties(
Schema_ref@1,
Ctx
)
end
),
Operation_needs_dict = gleam@list:any(
Operation_inline_schemas,
fun(Schema_ref@2) ->
oaspec@internal@codegen@schema_utils:schema_has_additional_properties(
Schema_ref@2,
Ctx
)
orelse oaspec@internal@codegen@schema_utils:schema_has_forbidden_additional_properties(
Schema_ref@2,
Ctx
)
end
),
Needs_dict = Component_needs_dict orelse Operation_needs_dict,
Needs_strict_oneof_runtime = gleam@list:any(
Schemas,
fun(Entry@3) ->
{_, Schema_ref@3} = Entry@3,
oaspec@internal@codegen@schema_utils:schema_has_non_discriminator_oneof(
Schema_ref@3,
Ctx
)
end
)
orelse gleam@list:any(
Operation_inline_schemas,
fun(Schema_ref@4) ->
oaspec@internal@codegen@schema_utils:schema_has_non_discriminator_oneof(
Schema_ref@4,
Ctx
)
end
),
Needs_types = gleam@list:any(
Schemas,
fun(Entry@4) ->
{_, Schema_ref@5} = Entry@4,
case Schema_ref@5 of
{inline, {object_schema, _, _, _, _, _, _}} ->
true;
{inline, {all_of_schema, _, _}} ->
true;
{inline, {one_of_schema, _, _, _}} ->
true;
{inline, {any_of_schema, _, _, _}} ->
true;
{inline, {string_schema, _, _, Enum_values, _, _, _}} when Enum_values =/= [] ->
true;
_ ->
false
end
end
),
Base_imports = case Needs_dict of
true ->
[<<"gleam/dict"/utf8>>,
<<"gleam/dynamic/decode"/utf8>>,
<<"gleam/json"/utf8>>];
false ->
[<<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>]
end,
Base_imports@1 = case Needs_strict_oneof_runtime of
true ->
lists:append(
Base_imports,
[<<"gleam/list"/utf8>>, <<"gleam/result"/utf8>>]
);
false ->
Base_imports
end,
Base_imports@2 = case Needs_types of
true ->
lists:append(
Base_imports@1,
[<<(oaspec@config:package(
oaspec@internal@codegen@context:config(Ctx)
))/binary,
"/types"/utf8>>]
);
false ->
Base_imports@1
end,
Needs_bare_option_type = gleam@list:any(
Schemas,
fun(Entry@5) ->
{_, Schema_ref@6} = Entry@5,
oaspec@internal@codegen@codec_helpers:schema_ref_has_bare_option_type(
Schema_ref@6
)
end
),
Imports = case {Needs_option, Needs_bare_option_type} of
{true, true} ->
lists:append(
Base_imports@2,
[<<"gleam/option.{type Option}"/utf8>>]
);
{true, false} ->
lists:append(Base_imports@2, [<<"gleam/option"/utf8>>]);
{false, _} ->
Base_imports@2
end,
Sb = begin
_pipe@1 = oaspec@internal@util@string_extra:file_header(
<<"0.56.0"/utf8>>
),
oaspec@internal@util@string_extra:imports(_pipe@1, Imports)
end,
Sb@2 = gleam@list:fold(
Schemas,
Sb,
fun(Sb@1, Entry@6) ->
{Name, Schema_ref@7} = Entry@6,
generate_inline_enum_decoders(Sb@1, Name, Schema_ref@7, Ctx)
end
),
Sb@4 = gleam@list:fold(
Schemas,
Sb@2,
fun(Sb@3, Entry@7) ->
{Name@1, Schema_ref@8} = Entry@7,
generate_decoder(Sb@3, Name@1, Schema_ref@8, Ctx)
end
),
Sb@5 = generate_anonymous_decoders(Sb@4, Ctx, Operations),
oaspec@internal@util@string_extra:to_string(Sb@5).
-file("src/oaspec/internal/codegen/decoders.gleam", 31).
?DOC(false).
-spec generate(oaspec@internal@codegen@context:context()) -> list(oaspec@internal@codegen@context:generated_file()).
generate(Ctx) ->
Operations = oaspec@internal@codegen@context:operations(Ctx),
Decode_content = generate_decoders(Ctx, Operations),
[{generated_file,
<<"decode.gleam"/utf8>>,
Decode_content,
shared_target,
overwrite}].