Packages
oaspec
0.3.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@codegen@decoders.erl
-module(oaspec@codegen@decoders).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaspec/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.
-file("src/oaspec/codegen/decoders.gleam", 194).
?DOC(" Status code suffix for anonymous type naming (shared with types.gleam).\n").
-spec status_code_suffix(binary()) -> binary().
status_code_suffix(Code) ->
case Code of
<<"200"/utf8>> ->
<<"Ok"/utf8>>;
<<"201"/utf8>> ->
<<"Created"/utf8>>;
<<"204"/utf8>> ->
<<"NoContent"/utf8>>;
<<"400"/utf8>> ->
<<"BadRequest"/utf8>>;
<<"401"/utf8>> ->
<<"Unauthorized"/utf8>>;
<<"403"/utf8>> ->
<<"Forbidden"/utf8>>;
<<"404"/utf8>> ->
<<"NotFound"/utf8>>;
<<"409"/utf8>> ->
<<"Conflict"/utf8>>;
<<"422"/utf8>> ->
<<"UnprocessableEntity"/utf8>>;
<<"500"/utf8>> ->
<<"InternalServerError"/utf8>>;
<<"default"/utf8>> ->
<<"Default"/utf8>>;
Other ->
<<"Status"/utf8, Other/binary>>
end.
-file("src/oaspec/codegen/decoders.gleam", 812).
?DOC(
" Get the discriminator value for a $ref.\n"
" OpenAPI discriminator.mapping is keyed by payload values, with $ref paths\n"
" as values: { \"dog\": \"#/components/schemas/Dog\" }.\n"
" Given a ref_name like \"Dog\", find the mapping key that points to it.\n"
" Falls back to ref_name if no explicit mapping exists.\n"
).
-spec get_discriminator_value(
oaspec@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@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/codegen/decoders.gleam", 833).
?DOC(
" Convert a SchemaRef to a decoder expression string.\n"
" parent_name is used to resolve inline enum decoder names.\n"
).
-spec schema_ref_to_decoder(
oaspec@openapi@schema:schema_ref(),
binary(),
binary(),
oaspec@codegen@context:context()
) -> binary().
schema_ref_to_decoder(Ref, Parent_name, Prop_name, Ctx) ->
_ = Ctx,
case Ref of
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Decoder_name = oaspec@util@naming:to_snake_case(
<<(oaspec@util@naming:schema_to_type_name(Parent_name))/binary,
(oaspec@util@naming:schema_to_type_name(Prop_name))/binary>>
),
<<Decoder_name/binary, "_decoder()"/utf8>>;
{inline, {string_schema, _, _, _, _, _, _, _}} ->
<<"decode.string"/utf8>>;
{inline, {integer_schema, _, _, _, _, _}} ->
<<"decode.int"/utf8>>;
{inline, {number_schema, _, _, _, _, _}} ->
<<"decode.float"/utf8>>;
{inline, {boolean_schema, _, _}} ->
<<"decode.bool"/utf8>>;
{inline, {array_schema, _, Items, _, _, _}} ->
Inner = schema_ref_to_decoder(Items, Parent_name, Prop_name, Ctx),
<<<<"decode.list("/utf8, Inner/binary>>/binary, ")"/utf8>>;
{reference, Ref@1} ->
Name = oaspec@openapi@resolver:ref_to_name(Ref@1),
<<(oaspec@util@naming:to_snake_case(Name))/binary,
"_decoder()"/utf8>>;
_ ->
<<"decode.string"/utf8>>
end.
-file("src/oaspec/codegen/decoders.gleam", 867).
?DOC(" Check if a SchemaRef has nullable: true.\n").
-spec schema_ref_is_nullable(
oaspec@openapi@schema:schema_ref(),
oaspec@codegen@context:context()
) -> boolean().
schema_ref_is_nullable(Ref, Ctx) ->
case Ref of
{inline, Schema} ->
oaspec@openapi@schema:is_nullable(Schema);
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
Ref,
erlang:element(2, Ctx)
) of
{ok, S} ->
oaspec@openapi@schema:is_nullable(S);
{error, _} ->
false
end
end.
-file("src/oaspec/codegen/decoders.gleam", 1386).
?DOC(
" Convert a SchemaRef to a json.Json encoder function reference.\n"
" Used for json.nullable(value, <fn>) and json.array(list, <fn>).\n"
).
-spec schema_ref_to_json_encoder_fn(
oaspec@openapi@schema:schema_ref(),
binary(),
binary(),
oaspec@codegen@context:context()
) -> binary().
schema_ref_to_json_encoder_fn(Ref, Parent_name, Prop_name, Ctx) ->
_ = Ctx,
case Ref of
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
<<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(
<<(oaspec@util@naming:schema_to_type_name(Parent_name))/binary,
(oaspec@util@naming:schema_to_type_name(Prop_name))/binary>>
))/binary>>/binary,
"_json"/utf8>>;
{inline, {string_schema, _, _, _, _, _, _, _}} ->
<<"json.string"/utf8>>;
{inline, {integer_schema, _, _, _, _, _}} ->
<<"json.int"/utf8>>;
{inline, {number_schema, _, _, _, _, _}} ->
<<"json.float"/utf8>>;
{inline, {boolean_schema, _, _}} ->
<<"json.bool"/utf8>>;
{inline, {array_schema, _, Items, _, _, _}} ->
Inner = schema_ref_to_json_encoder_fn(
Items,
Parent_name,
Prop_name,
Ctx
),
<<<<"fn(items) { json.array(items, "/utf8, Inner/binary>>/binary,
") }"/utf8>>;
{reference, Ref@1} ->
Name = oaspec@openapi@resolver:ref_to_name(Ref@1),
<<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(Name))/binary>>/binary,
"_json"/utf8>>;
_ ->
<<"json.string"/utf8>>
end.
-file("src/oaspec/codegen/decoders.gleam", 1349).
?DOC(
" Convert a SchemaRef to a json.Json encoder expression.\n"
" Returns an expression that produces json.Json (not String).\n"
).
-spec schema_ref_to_json_encoder(
binary(),
oaspec@openapi@schema:schema_ref(),
binary(),
binary(),
oaspec@codegen@context:context()
) -> binary().
schema_ref_to_json_encoder(Value_expr, Ref, Parent_name, Prop_name, Ctx) ->
case Ref of
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Fn_name = <<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(
<<(oaspec@util@naming:schema_to_type_name(Parent_name))/binary,
(oaspec@util@naming:schema_to_type_name(Prop_name))/binary>>
))/binary>>/binary,
"_json"/utf8>>,
<<<<<<Fn_name/binary, "("/utf8>>/binary, Value_expr/binary>>/binary,
")"/utf8>>;
{inline, {string_schema, _, _, _, _, _, _, _}} ->
<<<<"json.string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{inline, {integer_schema, _, _, _, _, _}} ->
<<<<"json.int("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{inline, {number_schema, _, _, _, _, _}} ->
<<<<"json.float("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{inline, {boolean_schema, _, _}} ->
<<<<"json.bool("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{inline, {array_schema, _, Items, _, _, _}} ->
Inner_fn = schema_ref_to_json_encoder_fn(
Items,
Parent_name,
Prop_name,
Ctx
),
<<<<<<<<"json.array("/utf8, Value_expr/binary>>/binary, ", "/utf8>>/binary,
Inner_fn/binary>>/binary,
")"/utf8>>;
{reference, Ref@1} ->
Name = oaspec@openapi@resolver:ref_to_name(Ref@1),
<<<<<<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(Name))/binary>>/binary,
"_json("/utf8>>/binary,
Value_expr/binary>>/binary,
")"/utf8>>;
_ ->
<<<<"json.string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>
end.
-file("src/oaspec/codegen/decoders.gleam", 1019).
?DOC(
" Generate an encoder function for a schema.\n"
" Each type gets two functions:\n"
" encode_x_json(value) -> json.Json (for composition in objects)\n"
" encode_x(value) -> String (for standalone use)\n"
).
-spec generate_encoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@schema:schema_ref(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_encoder(Sb, Name, Schema_ref, Ctx) ->
Type_name = oaspec@util@naming:schema_to_type_name(Name),
Fn_name = <<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(Name))/binary>>,
Json_fn_name = <<Fn_name/binary, "_json"/utf8>>,
case Schema_ref of
{inline, {object_schema, _, Properties, Required, _, _, _}} ->
Sb@1 = begin
_pipe = Sb,
_pipe@1 = oaspec@util@string_extra:line(
_pipe,
<<<<<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> json.Json {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@1,
1,
<<"json.object(["/utf8>>
)
end,
Props = maps:to_list(Properties),
Sb@3 = gleam@list:index_fold(
Props,
Sb@1,
fun(Sb@2, Entry, Idx) ->
{Prop_name, Prop_ref} = Entry,
Field_name = oaspec@util@naming:to_snake_case(Prop_name),
Is_required = gleam@list:contains(Required, Prop_name),
Trailing = case Idx =:= (erlang:length(Props) - 1) of
true ->
<<""/utf8>>;
false ->
<<","/utf8>>
end,
Encoder_expr = schema_ref_to_json_encoder(
<<"value."/utf8, Field_name/binary>>,
Prop_ref,
Name,
Prop_name,
Ctx
),
case Is_required of
true ->
_pipe@2 = Sb@2,
oaspec@util@string_extra:indent(
_pipe@2,
2,
<<<<<<<<<<"#(\""/utf8, Prop_name/binary>>/binary,
"\", "/utf8>>/binary,
Encoder_expr/binary>>/binary,
")"/utf8>>/binary,
Trailing/binary>>
);
false ->
_pipe@3 = Sb@2,
oaspec@util@string_extra:indent(
_pipe@3,
2,
<<<<<<<<<<<<<<"#(\""/utf8, Prop_name/binary>>/binary,
"\", json.nullable(value."/utf8>>/binary,
Field_name/binary>>/binary,
", "/utf8>>/binary,
(schema_ref_to_json_encoder_fn(
Prop_ref,
Name,
Prop_name,
Ctx
))/binary>>/binary,
"))"/utf8>>/binary,
Trailing/binary>>
)
end
end
),
Sb@4 = begin
_pipe@4 = Sb@3,
_pipe@5 = oaspec@util@string_extra:indent(
_pipe@4,
1,
<<"])"/utf8>>
),
_pipe@6 = oaspec@util@string_extra:line(_pipe@5, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@6)
end,
Sb@5 = begin
_pipe@7 = Sb@4,
_pipe@8 = oaspec@util@string_extra:line(
_pipe@7,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {"/utf8>>
),
_pipe@9 = oaspec@util@string_extra:indent(
_pipe@8,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@10 = oaspec@util@string_extra:line(_pipe@9, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@10)
end,
Sb@5;
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Sb@6 = begin
_pipe@11 = Sb,
_pipe@12 = oaspec@util@string_extra:line(
_pipe@11,
<<<<<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> json.Json {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@12,
1,
<<"let str = case value {"/utf8>>
)
end,
Sb@8 = gleam@list:fold(
Enum_values,
Sb@6,
fun(Sb@7, Value) ->
Variant = oaspec@util@naming:schema_to_type_name(
<<<<Type_name/binary, "_"/utf8>>/binary, Value/binary>>
),
_pipe@13 = Sb@7,
oaspec@util@string_extra:indent(
_pipe@13,
2,
<<<<<<<<"types."/utf8, Variant/binary>>/binary,
" -> \""/utf8>>/binary,
Value/binary>>/binary,
"\""/utf8>>
)
end
),
Sb@9 = begin
_pipe@14 = Sb@8,
_pipe@15 = oaspec@util@string_extra:indent(
_pipe@14,
1,
<<"}"/utf8>>
),
_pipe@16 = oaspec@util@string_extra:indent(
_pipe@15,
1,
<<"json.string(str)"/utf8>>
),
_pipe@17 = oaspec@util@string_extra:line(_pipe@16, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@17)
end,
Sb@10 = begin
_pipe@18 = Sb@9,
_pipe@19 = oaspec@util@string_extra:line(
_pipe@18,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {"/utf8>>
),
_pipe@20 = oaspec@util@string_extra:indent(
_pipe@19,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@21 = oaspec@util@string_extra:line(_pipe@20, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@21)
end,
To_string_fn_name = <<Fn_name/binary, "_to_string"/utf8>>,
Sb@11 = begin
_pipe@22 = Sb@10,
_pipe@23 = oaspec@util@string_extra:line(
_pipe@22,
<<<<<<<<"pub fn "/utf8, To_string_fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@23,
1,
<<"case value {"/utf8>>
)
end,
Sb@13 = gleam@list:fold(
Enum_values,
Sb@11,
fun(Sb@12, Value@1) ->
Variant@1 = oaspec@util@naming:schema_to_type_name(
<<<<Type_name/binary, "_"/utf8>>/binary,
Value@1/binary>>
),
_pipe@24 = Sb@12,
oaspec@util@string_extra:indent(
_pipe@24,
2,
<<<<<<<<"types."/utf8, Variant@1/binary>>/binary,
" -> \""/utf8>>/binary,
Value@1/binary>>/binary,
"\""/utf8>>
)
end
),
Sb@14 = begin
_pipe@25 = Sb@13,
_pipe@26 = oaspec@util@string_extra:indent(
_pipe@25,
1,
<<"}"/utf8>>
),
_pipe@27 = oaspec@util@string_extra:line(_pipe@26, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@27)
end,
Sb@14;
{inline, {all_of_schema, Description, Schemas}} ->
Merged_props = gleam@list:fold(
Schemas,
maps:new(),
fun(Acc, S_ref) -> case S_ref of
{inline, {object_schema, _, Properties@1, _, _, _, _}} ->
maps:merge(Acc, Properties@1);
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref,
erlang:element(2, Ctx)
) of
{ok,
{object_schema, _, Properties@2, _, _, _, _}} ->
maps:merge(Acc, Properties@2);
_ ->
Acc
end;
_ ->
Acc
end end
),
Merged_required = gleam@list:flat_map(
Schemas,
fun(S_ref@1) -> case S_ref@1 of
{inline, {object_schema, _, _, Required@1, _, _, _}} ->
Required@1;
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref@1,
erlang:element(2, Ctx)
) of
{ok, {object_schema, _, _, Required@2, _, _, _}} ->
Required@2;
_ ->
[]
end;
_ ->
[]
end end
),
Merged_schema = {inline,
{object_schema,
Description,
Merged_props,
Merged_required,
none,
false,
false}},
generate_encoder(Sb, Name, Merged_schema, Ctx);
{inline, {one_of_schema, _, Schemas@1, _}} ->
All_refs = gleam@list:all(Schemas@1, fun(S) -> case S of
{reference, _} ->
true;
_ ->
false
end end),
case All_refs of
false ->
Sb;
true ->
Sb@15 = begin
_pipe@28 = Sb,
_pipe@29 = oaspec@util@string_extra:line(
_pipe@28,
<<<<<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> json.Json {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@29,
1,
<<"case value {"/utf8>>
)
end,
Sb@17 = gleam@list:fold(
Schemas@1,
Sb@15,
fun(Sb@16, S_ref@2) -> case S_ref@2 of
{reference, Ref} ->
Ref_name = oaspec@openapi@resolver:ref_to_name(
Ref
),
Variant_type = oaspec@util@naming:schema_to_type_name(
Ref_name
),
Variant_name = <<Type_name/binary,
Variant_type/binary>>,
Inner_encoder = <<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(
Ref_name
))/binary>>/binary,
"_json"/utf8>>,
_pipe@30 = Sb@16,
oaspec@util@string_extra:indent(
_pipe@30,
2,
<<<<<<<<"types."/utf8,
Variant_name/binary>>/binary,
"(inner) -> "/utf8>>/binary,
Inner_encoder/binary>>/binary,
"(inner)"/utf8>>
);
_ ->
Sb@16
end end
),
Sb@18 = begin
_pipe@31 = Sb@17,
_pipe@32 = oaspec@util@string_extra:indent(
_pipe@31,
1,
<<"}"/utf8>>
),
_pipe@33 = oaspec@util@string_extra:line(
_pipe@32,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@33)
end,
Sb@19 = begin
_pipe@34 = Sb@18,
_pipe@35 = oaspec@util@string_extra:line(
_pipe@34,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {"/utf8>>
),
_pipe@36 = oaspec@util@string_extra:indent(
_pipe@35,
1,
<<Json_fn_name/binary,
"(value) |> json.to_string()"/utf8>>
),
_pipe@37 = oaspec@util@string_extra:line(
_pipe@36,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@37)
end,
Sb@19
end;
{inline, {any_of_schema, _, Schemas@1}} ->
All_refs = gleam@list:all(Schemas@1, fun(S) -> case S of
{reference, _} ->
true;
_ ->
false
end end),
case All_refs of
false ->
Sb;
true ->
Sb@15 = begin
_pipe@28 = Sb,
_pipe@29 = oaspec@util@string_extra:line(
_pipe@28,
<<<<<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> json.Json {"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@29,
1,
<<"case value {"/utf8>>
)
end,
Sb@17 = gleam@list:fold(
Schemas@1,
Sb@15,
fun(Sb@16, S_ref@2) -> case S_ref@2 of
{reference, Ref} ->
Ref_name = oaspec@openapi@resolver:ref_to_name(
Ref
),
Variant_type = oaspec@util@naming:schema_to_type_name(
Ref_name
),
Variant_name = <<Type_name/binary,
Variant_type/binary>>,
Inner_encoder = <<<<"encode_"/utf8,
(oaspec@util@naming:to_snake_case(
Ref_name
))/binary>>/binary,
"_json"/utf8>>,
_pipe@30 = Sb@16,
oaspec@util@string_extra:indent(
_pipe@30,
2,
<<<<<<<<"types."/utf8,
Variant_name/binary>>/binary,
"(inner) -> "/utf8>>/binary,
Inner_encoder/binary>>/binary,
"(inner)"/utf8>>
);
_ ->
Sb@16
end end
),
Sb@18 = begin
_pipe@31 = Sb@17,
_pipe@32 = oaspec@util@string_extra:indent(
_pipe@31,
1,
<<"}"/utf8>>
),
_pipe@33 = oaspec@util@string_extra:line(
_pipe@32,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@33)
end,
Sb@19 = begin
_pipe@34 = Sb@18,
_pipe@35 = oaspec@util@string_extra:line(
_pipe@34,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: types."/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {"/utf8>>
),
_pipe@36 = oaspec@util@string_extra:indent(
_pipe@35,
1,
<<Json_fn_name/binary,
"(value) |> json.to_string()"/utf8>>
),
_pipe@37 = oaspec@util@string_extra:line(
_pipe@36,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@37)
end,
Sb@19
end;
{inline, {string_schema, _, _, [], _, _, _, _}} ->
_pipe@38 = Sb,
_pipe@39 = oaspec@util@string_extra:line(
_pipe@38,
<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: String) -> json.Json {"/utf8>>
),
_pipe@40 = oaspec@util@string_extra:indent(
_pipe@39,
1,
<<"json.string(value)"/utf8>>
),
_pipe@41 = oaspec@util@string_extra:line(_pipe@40, <<"}"/utf8>>),
_pipe@42 = oaspec@util@string_extra:blank_line(_pipe@41),
_pipe@43 = oaspec@util@string_extra:line(
_pipe@42,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: String) -> String {"/utf8>>
),
_pipe@44 = oaspec@util@string_extra:indent(
_pipe@43,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@45 = oaspec@util@string_extra:line(_pipe@44, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@45);
{inline, {integer_schema, _, _, _, _, _}} ->
_pipe@46 = Sb,
_pipe@47 = oaspec@util@string_extra:line(
_pipe@46,
<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: Int) -> json.Json {"/utf8>>
),
_pipe@48 = oaspec@util@string_extra:indent(
_pipe@47,
1,
<<"json.int(value)"/utf8>>
),
_pipe@49 = oaspec@util@string_extra:line(_pipe@48, <<"}"/utf8>>),
_pipe@50 = oaspec@util@string_extra:blank_line(_pipe@49),
_pipe@51 = oaspec@util@string_extra:line(
_pipe@50,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: Int) -> String {"/utf8>>
),
_pipe@52 = oaspec@util@string_extra:indent(
_pipe@51,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@53 = oaspec@util@string_extra:line(_pipe@52, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@53);
{inline, {number_schema, _, _, _, _, _}} ->
_pipe@54 = Sb,
_pipe@55 = oaspec@util@string_extra:line(
_pipe@54,
<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: Float) -> json.Json {"/utf8>>
),
_pipe@56 = oaspec@util@string_extra:indent(
_pipe@55,
1,
<<"json.float(value)"/utf8>>
),
_pipe@57 = oaspec@util@string_extra:line(_pipe@56, <<"}"/utf8>>),
_pipe@58 = oaspec@util@string_extra:blank_line(_pipe@57),
_pipe@59 = oaspec@util@string_extra:line(
_pipe@58,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: Float) -> String {"/utf8>>
),
_pipe@60 = oaspec@util@string_extra:indent(
_pipe@59,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@61 = oaspec@util@string_extra:line(_pipe@60, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@61);
{inline, {boolean_schema, _, _}} ->
_pipe@62 = Sb,
_pipe@63 = oaspec@util@string_extra:line(
_pipe@62,
<<<<"pub fn "/utf8, Json_fn_name/binary>>/binary,
"(value: Bool) -> json.Json {"/utf8>>
),
_pipe@64 = oaspec@util@string_extra:indent(
_pipe@63,
1,
<<"json.bool(value)"/utf8>>
),
_pipe@65 = oaspec@util@string_extra:line(_pipe@64, <<"}"/utf8>>),
_pipe@66 = oaspec@util@string_extra:blank_line(_pipe@65),
_pipe@67 = oaspec@util@string_extra:line(
_pipe@66,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(value: Bool) -> String {"/utf8>>
),
_pipe@68 = oaspec@util@string_extra:indent(
_pipe@67,
1,
<<Json_fn_name/binary, "(value) |> json.to_string()"/utf8>>
),
_pipe@69 = oaspec@util@string_extra:line(_pipe@68, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@69);
_ ->
Sb
end.
-file("src/oaspec/codegen/decoders.gleam", 937).
?DOC(" Generate inline enum encoders found in object/allOf properties.\n").
-spec generate_inline_enum_encoders(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@schema:schema_ref(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_inline_enum_encoders(Sb, Parent_name, Schema_ref, Ctx) ->
Props = case Schema_ref of
{inline, {object_schema, _, Properties, _, _, _, _}} ->
maps:to_list(Properties);
{inline, {all_of_schema, _, Schemas}} ->
Merged = gleam@list:fold(
Schemas,
maps:new(),
fun(Acc, S_ref) -> case S_ref of
{inline, {object_schema, _, Properties@1, _, _, _, _}} ->
maps:merge(Acc, Properties@1);
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref,
erlang:element(2, Ctx)
) of
{ok,
{object_schema, _, Properties@2, _, _, _, _}} ->
maps:merge(Acc, Properties@2);
_ ->
Acc
end;
_ ->
Acc
end end
),
maps:to_list(Merged);
_ ->
[]
end,
gleam@list:fold(
Props,
Sb,
fun(Sb@1, Entry) ->
{Prop_name, Prop_ref} = Entry,
case Prop_ref of
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Enum_name = <<(oaspec@util@naming:schema_to_type_name(
Parent_name
))/binary,
(oaspec@util@naming:schema_to_type_name(Prop_name))/binary>>,
generate_encoder(Sb@1, Enum_name, Prop_ref, Ctx);
_ ->
Sb@1
end
end
).
-file("src/oaspec/codegen/decoders.gleam", 990).
?DOC(" Generate encoder for an inline requestBody schema.\n").
-spec generate_anonymous_request_body_encoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@spec:operation(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_request_body_encoder(Sb, Op_id, Operation, Ctx) ->
case erlang:element(7, Operation) of
{some, Rb} ->
Content_entries = maps:to_list(erlang:element(3, Rb)),
case Content_entries of
[{_, Media_type} | _] ->
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
Name = <<(oaspec@util@naming:to_snake_case(Op_id))/binary,
"_request_body"/utf8>>,
generate_encoder(
Sb,
Name,
{inline, Schema_obj},
Ctx
);
_ ->
Sb
end;
_ ->
Sb
end;
none ->
Sb
end.
-file("src/oaspec/codegen/decoders.gleam", 977).
?DOC(" Generate encoders for anonymous inline schemas (response/requestBody).\n").
-spec generate_anonymous_encoders(
gleam@string_tree:string_tree(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_encoders(Sb, Ctx) ->
Operations = oaspec@codegen@types:collect_operations(Ctx),
gleam@list:fold(
Operations,
Sb,
fun(Sb@1, Op) ->
{Op_id, Operation, _, _} = Op,
generate_anonymous_request_body_encoder(Sb@1, Op_id, Operation, Ctx)
end
).
-file("src/oaspec/codegen/decoders.gleam", 883).
?DOC(" Generate JSON encoders for all component schemas and anonymous types.\n").
-spec generate_encoders(oaspec@codegen@context:context()) -> binary().
generate_encoders(Ctx) ->
Schemas = case erlang:element(5, erlang:element(2, Ctx)) of
{some, Components} ->
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
);
none ->
[]
end,
Needs_types = gleam@list:any(
Schemas,
fun(Entry) ->
{_, Schema_ref} = Entry,
case Schema_ref 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 = [<<"gleam/json"/utf8>>],
Imports = case Needs_types of
true ->
lists:append(
Base_imports,
[<<(erlang:element(5, erlang:element(3, Ctx)))/binary,
"/types"/utf8>>]
);
false ->
Base_imports
end,
Sb = begin
_pipe = oaspec@util@string_extra:file_header(<<"0.3.0"/utf8>>),
oaspec@util@string_extra:imports(_pipe, Imports)
end,
Sb@2 = gleam@list:fold(
Schemas,
Sb,
fun(Sb@1, Entry@1) ->
{Name, Schema_ref@1} = Entry@1,
generate_inline_enum_encoders(Sb@1, Name, Schema_ref@1, Ctx)
end
),
Sb@4 = gleam@list:fold(
Schemas,
Sb@2,
fun(Sb@3, Entry@2) ->
{Name@1, Schema_ref@2} = Entry@2,
generate_encoder(Sb@3, Name@1, Schema_ref@2, Ctx)
end
),
Sb@5 = generate_anonymous_encoders(Sb@4, Ctx),
oaspec@util@string_extra:to_string(Sb@5).
-file("src/oaspec/codegen/decoders.gleam", 1420).
?DOC(" Add a doc comment if description is present.\n").
-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@util@string_extra:doc_comment(_pipe, Desc);
none ->
Sb
end.
-file("src/oaspec/codegen/decoders.gleam", 623).
?DOC(
" Generate decoder for oneOf/anyOf union types.\n"
" With discriminator: decode based on discriminator field value.\n"
" Without discriminator: try each variant decoder in order.\n"
).
-spec generate_oneof_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
binary(),
binary(),
gleam@option:option(binary()),
list(oaspec@openapi@schema:schema_ref()),
gleam@option:option(oaspec@openapi@schema:discriminator()),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_oneof_decoder(
Sb,
_,
Type_name,
Fn_name,
Decoder_fn_name,
Description,
Schemas,
Discriminator,
Ctx
) ->
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@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@util@string_extra:indent(
_pipe@1,
1,
<<<<"use disc_value <- decode.field(\""/utf8,
(erlang:element(2, Disc))/binary>>/binary,
"\", decode.string)"/utf8>>
),
oaspec@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} ->
Ref_name = oaspec@openapi@resolver:ref_to_name(
Ref
),
Variant_type = oaspec@util@naming:schema_to_type_name(
Ref_name
),
Variant_name = <<Type_name/binary,
Variant_type/binary>>,
Variant_decoder = <<(oaspec@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@util@string_extra:indent(
_pipe@3,
2,
<<<<"\""/utf8, Disc_value/binary>>/binary,
"\" -> {"/utf8>>
),
_pipe@5 = oaspec@util@string_extra:indent(
_pipe@4,
3,
<<<<"use inner <- decode.then("/utf8,
Variant_decoder/binary>>/binary,
")"/utf8>>
),
_pipe@6 = oaspec@util@string_extra:indent(
_pipe@5,
3,
<<<<"decode.success(types."/utf8,
Variant_name/binary>>/binary,
"(inner))"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@6,
2,
<<"}"/utf8>>
);
_ ->
Sb@3
end end
),
First_ref_decoder = case Schemas of
[{reference, Ref@1} | _] ->
Ref_name@1 = oaspec@openapi@resolver:ref_to_name(
Ref@1
),
<<(oaspec@util@naming:to_snake_case(Ref_name@1))/binary,
"_decoder()"/utf8>>;
_ ->
<<"decode.string"/utf8>>
end,
First_variant_name = case Schemas of
[{reference, Ref@2} | _] ->
Ref_name@2 = oaspec@openapi@resolver:ref_to_name(
Ref@2
),
Variant_type@1 = oaspec@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,
Sb@5 = begin
_pipe@7 = Sb@4,
_pipe@8 = oaspec@util@string_extra:indent(
_pipe@7,
2,
<<"_ -> {"/utf8>>
),
_pipe@9 = oaspec@util@string_extra:indent(
_pipe@8,
3,
<<<<"use v <- decode.then("/utf8,
First_ref_decoder/binary>>/binary,
")"/utf8>>
),
_pipe@10 = oaspec@util@string_extra:indent(
_pipe@9,
3,
<<<<<<<<"decode.failure("/utf8,
First_variant_name/binary>>/binary,
"(v), \""/utf8>>/binary,
Type_name/binary>>/binary,
"\")"/utf8>>
),
_pipe@11 = oaspec@util@string_extra:indent(
_pipe@10,
2,
<<"}"/utf8>>
),
_pipe@12 = oaspec@util@string_extra:indent(
_pipe@11,
1,
<<"}"/utf8>>
),
_pipe@13 = oaspec@util@string_extra:line(
_pipe@12,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@13)
end,
Sb@6 = begin
_pipe@14 = Sb@5,
_pipe@15 = oaspec@util@string_extra:line(
_pipe@14,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@16 = oaspec@util@string_extra:indent(
_pipe@15,
1,
<<<<"json.parse(json_string, "/utf8,
Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@17 = oaspec@util@string_extra:line(
_pipe@16,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@17)
end,
Sb@6;
none ->
Sb@7 = begin
_pipe@18 = Sb@1,
oaspec@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>>
)
end,
Sb@9 = gleam@list:fold(
Schemas,
Sb@7,
fun(Sb@8, S_ref@1) -> case S_ref@1 of
{reference, Ref@3} ->
Ref_name@3 = oaspec@openapi@resolver:ref_to_name(
Ref@3
),
Variant_type@2 = oaspec@util@naming:schema_to_type_name(
Ref_name@3
),
Variant_name@1 = <<Type_name/binary,
Variant_type@2/binary>>,
Decode_fn = <<"decode_"/utf8,
(oaspec@util@naming:to_snake_case(
Ref_name@3
))/binary>>,
_pipe@19 = Sb@8,
_pipe@20 = oaspec@util@string_extra:indent(
_pipe@19,
1,
<<<<"case "/utf8, Decode_fn/binary>>/binary,
"(json_string) {"/utf8>>
),
_pipe@21 = oaspec@util@string_extra:indent(
_pipe@20,
2,
<<<<"Ok(v) -> Ok(types."/utf8,
Variant_name@1/binary>>/binary,
"(v))"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@21,
2,
<<"Error(_) ->"/utf8>>
);
_ ->
Sb@8
end end
),
Sb@10 = begin
_pipe@22 = Sb@9,
oaspec@util@string_extra:indent(
_pipe@22,
1,
<<"Error(json.UnexpectedEndOfInput)"/utf8>>
)
end,
Sb@12 = gleam@list:fold(
gleam@list:repeat(nil, erlang:length(Schemas)),
Sb@10,
fun(Sb@11, _) -> _pipe@23 = Sb@11,
oaspec@util@string_extra:indent(
_pipe@23,
1,
<<"}"/utf8>>
) end
),
Sb@13 = begin
_pipe@24 = Sb@12,
_pipe@25 = oaspec@util@string_extra:line(
_pipe@24,
<<"}"/utf8>>
),
oaspec@util@string_extra:blank_line(_pipe@25)
end,
_ = Ctx,
Sb@13
end
end.
-file("src/oaspec/codegen/decoders.gleam", 252).
?DOC(" Generate decoder functions for a schema.\n").
-spec generate_decoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@schema:schema_ref(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_decoder(Sb, Name, Schema_ref, Ctx) ->
Type_name = oaspec@util@naming:schema_to_type_name(Name),
Fn_name = <<"decode_"/utf8,
(oaspec@util@naming:to_snake_case(Name))/binary>>,
Decoder_fn_name = <<(oaspec@util@naming:to_snake_case(Name))/binary,
"_decoder"/utf8>>,
case Schema_ref of
{inline,
{object_schema, Description, Properties, Required, _, _, Nullable}} ->
Sb@1 = maybe_doc_comment(Sb, Description),
Sb@2 = begin
_pipe = Sb@1,
oaspec@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 = maps:to_list(Properties),
Sb@4 = gleam@list:fold(
Props,
Sb@2,
fun(Sb@3, Entry) ->
{Prop_name, Prop_ref} = Entry,
Field_name = oaspec@util@naming:to_snake_case(Prop_name),
Is_required = gleam@list:contains(Required, Prop_name),
Field_decoder = schema_ref_to_decoder(
Prop_ref,
Name,
Prop_name,
Ctx
),
Is_nullable_schema = 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 Is_required of
true ->
_pipe@1 = Sb@3,
oaspec@util@string_extra:indent(
_pipe@1,
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@2 = Sb@3,
oaspec@util@string_extra:indent(
_pipe@2,
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@3 = Sb@3,
oaspec@util@string_extra:indent(
_pipe@3,
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
),
Param_names = gleam@list:map(
Props,
fun(Entry@1) ->
{Prop_name@1, _} = Entry@1,
Field_name@1 = oaspec@util@naming:to_snake_case(Prop_name@1),
<<<<Field_name@1/binary, ": "/utf8>>/binary,
Field_name@1/binary>>
end
),
Sb@5 = begin
_pipe@4 = Sb@4,
oaspec@util@string_extra:indent(
_pipe@4,
1,
<<<<<<<<"decode.success(types."/utf8, Type_name/binary>>/binary,
"("/utf8>>/binary,
(oaspec@util@string_extra:join_with(
Param_names,
<<", "/utf8>>
))/binary>>/binary,
"))"/utf8>>
)
end,
Sb@6 = begin
_pipe@5 = Sb@5,
_pipe@6 = oaspec@util@string_extra:line(_pipe@5, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@6)
end,
Sb@7 = begin
_pipe@7 = Sb@6,
_pipe@8 = oaspec@util@string_extra:line(
_pipe@7,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@9 = oaspec@util@string_extra:indent(
_pipe@8,
1,
<<<<"json.parse(json_string, "/utf8,
Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@10 = oaspec@util@string_extra:line(_pipe@9, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@10)
end,
List_fn_name = <<Fn_name/binary, "_list"/utf8>>,
List_decoder_fn_name = <<Decoder_fn_name/binary, "_list"/utf8>>,
Sb@8 = begin
_pipe@11 = Sb@7,
_pipe@12 = oaspec@util@string_extra:line(
_pipe@11,
<<<<<<<<"pub fn "/utf8, List_decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(List(types."/utf8>>/binary,
Type_name/binary>>/binary,
")) {"/utf8>>
),
_pipe@13 = oaspec@util@string_extra:indent(
_pipe@12,
1,
<<<<"decode.list("/utf8, Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@14 = oaspec@util@string_extra:line(_pipe@13, <<"}"/utf8>>),
_pipe@15 = oaspec@util@string_extra:blank_line(_pipe@14),
_pipe@16 = oaspec@util@string_extra:line(
_pipe@15,
<<<<<<<<"pub fn "/utf8, List_fn_name/binary>>/binary,
"(json_string: String) -> Result(List(types."/utf8>>/binary,
Type_name/binary>>/binary,
"), json.DecodeError) {"/utf8>>
),
_pipe@17 = oaspec@util@string_extra:indent(
_pipe@16,
1,
<<<<"json.parse(json_string, "/utf8,
List_decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@18 = oaspec@util@string_extra:line(_pipe@17, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@18)
end,
_ = Nullable,
Sb@8;
{inline, {string_schema, Description@1, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Sb@9 = maybe_doc_comment(Sb, Description@1),
Sb@10 = begin
_pipe@19 = Sb@9,
_pipe@20 = oaspec@util@string_extra:line(
_pipe@19,
<<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(types."/utf8>>/binary,
Type_name/binary>>/binary,
") {"/utf8>>
),
_pipe@21 = oaspec@util@string_extra:indent(
_pipe@20,
1,
<<"use value <- decode.then(decode.string)"/utf8>>
),
oaspec@util@string_extra:indent(
_pipe@21,
1,
<<"case value {"/utf8>>
)
end,
Sb@12 = gleam@list:fold(
Enum_values,
Sb@10,
fun(Sb@11, Value) ->
Variant = oaspec@util@naming:schema_to_type_name(
<<<<Type_name/binary, "_"/utf8>>/binary, Value/binary>>
),
_pipe@22 = Sb@11,
oaspec@util@string_extra:indent(
_pipe@22,
2,
<<<<<<<<"\""/utf8, Value/binary>>/binary,
"\" -> decode.success(types."/utf8>>/binary,
Variant/binary>>/binary,
")"/utf8>>
)
end
),
Sb@13 = begin
_pipe@23 = Sb@12,
_pipe@24 = oaspec@util@string_extra:indent(
_pipe@23,
2,
<<<<<<<<"_ -> decode.failure(types."/utf8,
(oaspec@util@naming:schema_to_type_name(
<<<<Type_name/binary, "_"/utf8>>/binary,
((case Enum_values of
[First | _] ->
First;
[] ->
<<"unknown"/utf8>>
end))/binary>>
))/binary>>/binary,
", \""/utf8>>/binary,
Type_name/binary>>/binary,
"\")"/utf8>>
),
_pipe@25 = oaspec@util@string_extra:indent(
_pipe@24,
1,
<<"}"/utf8>>
),
_pipe@26 = oaspec@util@string_extra:line(_pipe@25, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@26)
end,
Sb@14 = begin
_pipe@27 = Sb@13,
_pipe@28 = oaspec@util@string_extra:line(
_pipe@27,
<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(types."/utf8>>/binary,
Type_name/binary>>/binary,
", json.DecodeError) {"/utf8>>
),
_pipe@29 = oaspec@util@string_extra:indent(
_pipe@28,
1,
<<<<"json.parse(json_string, "/utf8,
Decoder_fn_name/binary>>/binary,
"())"/utf8>>
),
_pipe@30 = oaspec@util@string_extra:line(_pipe@29, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@30)
end,
Sb@14;
{inline, {all_of_schema, Description@2, Schemas}} ->
Merged_props = gleam@list:fold(
Schemas,
maps:new(),
fun(Acc, S_ref) -> case S_ref of
{inline, {object_schema, _, Properties@1, _, _, _, _}} ->
maps:merge(Acc, Properties@1);
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref,
erlang:element(2, Ctx)
) of
{ok,
{object_schema, _, Properties@2, _, _, _, _}} ->
maps:merge(Acc, Properties@2);
_ ->
Acc
end;
_ ->
Acc
end end
),
Merged_required = gleam@list:flat_map(
Schemas,
fun(S_ref@1) -> case S_ref@1 of
{inline, {object_schema, _, _, Required@1, _, _, _}} ->
Required@1;
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref@1,
erlang:element(2, Ctx)
) of
{ok, {object_schema, _, _, Required@2, _, _, _}} ->
Required@2;
_ ->
[]
end;
_ ->
[]
end end
),
Merged_schema = {inline,
{object_schema,
Description@2,
Merged_props,
Merged_required,
none,
false,
false}},
generate_decoder(Sb, Name, Merged_schema, Ctx);
{inline, {one_of_schema, Description@3, Schemas@1, Discriminator}} ->
generate_oneof_decoder(
Sb,
Name,
Type_name,
Fn_name,
Decoder_fn_name,
Description@3,
Schemas@1,
Discriminator,
Ctx
);
{inline, {any_of_schema, Description@4, Schemas@2}} ->
generate_oneof_decoder(
Sb,
Name,
Type_name,
Fn_name,
Decoder_fn_name,
Description@4,
Schemas@2,
none,
Ctx
);
{inline, {string_schema, _, _, [], _, _, _, _}} ->
Sb@15 = begin
_pipe@31 = Sb,
_pipe@32 = oaspec@util@string_extra:line(
_pipe@31,
<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(String) {"/utf8>>
),
_pipe@33 = oaspec@util@string_extra:indent(
_pipe@32,
1,
<<"decode.string"/utf8>>
),
_pipe@34 = oaspec@util@string_extra:line(_pipe@33, <<"}"/utf8>>),
_pipe@35 = oaspec@util@string_extra:blank_line(_pipe@34),
_pipe@36 = oaspec@util@string_extra:line(
_pipe@35,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(String, json.DecodeError) {"/utf8>>
),
_pipe@37 = oaspec@util@string_extra:indent(
_pipe@36,
1,
<<"json.parse(json_string, decode.string)"/utf8>>
),
_pipe@38 = oaspec@util@string_extra:line(_pipe@37, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@38)
end,
Sb@15;
{inline, {integer_schema, _, _, _, _, _}} ->
Sb@16 = begin
_pipe@39 = Sb,
_pipe@40 = oaspec@util@string_extra:line(
_pipe@39,
<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(Int) {"/utf8>>
),
_pipe@41 = oaspec@util@string_extra:indent(
_pipe@40,
1,
<<"decode.int"/utf8>>
),
_pipe@42 = oaspec@util@string_extra:line(_pipe@41, <<"}"/utf8>>),
_pipe@43 = oaspec@util@string_extra:blank_line(_pipe@42),
_pipe@44 = oaspec@util@string_extra:line(
_pipe@43,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(Int, json.DecodeError) {"/utf8>>
),
_pipe@45 = oaspec@util@string_extra:indent(
_pipe@44,
1,
<<"json.parse(json_string, decode.int)"/utf8>>
),
_pipe@46 = oaspec@util@string_extra:line(_pipe@45, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@46)
end,
Sb@16;
{inline, {number_schema, _, _, _, _, _}} ->
Sb@17 = begin
_pipe@47 = Sb,
_pipe@48 = oaspec@util@string_extra:line(
_pipe@47,
<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(Float) {"/utf8>>
),
_pipe@49 = oaspec@util@string_extra:indent(
_pipe@48,
1,
<<"decode.float"/utf8>>
),
_pipe@50 = oaspec@util@string_extra:line(_pipe@49, <<"}"/utf8>>),
_pipe@51 = oaspec@util@string_extra:blank_line(_pipe@50),
_pipe@52 = oaspec@util@string_extra:line(
_pipe@51,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(Float, json.DecodeError) {"/utf8>>
),
_pipe@53 = oaspec@util@string_extra:indent(
_pipe@52,
1,
<<"json.parse(json_string, decode.float)"/utf8>>
),
_pipe@54 = oaspec@util@string_extra:line(_pipe@53, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@54)
end,
Sb@17;
{inline, {boolean_schema, _, _}} ->
Sb@18 = begin
_pipe@55 = Sb,
_pipe@56 = oaspec@util@string_extra:line(
_pipe@55,
<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary,
"() -> decode.Decoder(Bool) {"/utf8>>
),
_pipe@57 = oaspec@util@string_extra:indent(
_pipe@56,
1,
<<"decode.bool"/utf8>>
),
_pipe@58 = oaspec@util@string_extra:line(_pipe@57, <<"}"/utf8>>),
_pipe@59 = oaspec@util@string_extra:blank_line(_pipe@58),
_pipe@60 = oaspec@util@string_extra:line(
_pipe@59,
<<<<"pub fn "/utf8, Fn_name/binary>>/binary,
"(json_string: String) -> Result(Bool, json.DecodeError) {"/utf8>>
),
_pipe@61 = oaspec@util@string_extra:indent(
_pipe@60,
1,
<<"json.parse(json_string, decode.bool)"/utf8>>
),
_pipe@62 = oaspec@util@string_extra:line(_pipe@61, <<"}"/utf8>>),
oaspec@util@string_extra:blank_line(_pipe@62)
end,
Sb@18;
_ ->
Sb
end.
-file("src/oaspec/codegen/decoders.gleam", 181).
?DOC(" Generate decoder for an anonymous schema with a composed name.\n").
-spec generate_anonymous_schema_decoder(
gleam@string_tree:string_tree(),
binary(),
binary(),
oaspec@openapi@schema:schema_object(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_schema_decoder(Sb, Op_id, Suffix, Schema_obj, Ctx) ->
Name = <<<<(oaspec@util@naming:to_snake_case(Op_id))/binary, "_"/utf8>>/binary,
(oaspec@util@naming:to_snake_case(Suffix))/binary>>,
Schema_ref = {inline, Schema_obj},
generate_decoder(Sb, Name, Schema_ref, Ctx).
-file("src/oaspec/codegen/decoders.gleam", 120).
?DOC(" Generate decoders for inline response schemas.\n").
-spec generate_anonymous_response_decoders(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@spec:operation(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_response_decoders(Sb, Op_id, Operation, Ctx) ->
Responses = maps:to_list(erlang:element(8, Operation)),
gleam@list:fold(
Responses,
Sb,
fun(Sb@1, Entry) ->
{Status_code, Response} = Entry,
Content_entries = maps:to_list(erlang:element(3, Response)),
case Content_entries of
[{_, Media_type} | _] ->
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
Suffix = <<"Response"/utf8,
(status_code_suffix(Status_code))/binary>>,
generate_anonymous_schema_decoder(
Sb@1,
Op_id,
Suffix,
Schema_obj,
Ctx
);
_ ->
Sb@1
end;
_ ->
Sb@1
end
end
).
-file("src/oaspec/codegen/decoders.gleam", 151).
?DOC(" Generate decoder for an inline requestBody schema.\n").
-spec generate_anonymous_request_body_decoder(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@spec:operation(),
oaspec@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, Rb} ->
Content_entries = maps:to_list(erlang:element(3, Rb)),
case Content_entries of
[{_, Media_type} | _] ->
case erlang:element(2, Media_type) of
{some, {inline, Schema_obj}} ->
generate_anonymous_schema_decoder(
Sb,
Op_id,
<<"RequestBody"/utf8>>,
Schema_obj,
Ctx
);
_ ->
Sb
end;
_ ->
Sb
end;
none ->
Sb
end.
-file("src/oaspec/codegen/decoders.gleam", 106).
?DOC(" Generate decoders for anonymous inline schemas (response/requestBody).\n").
-spec generate_anonymous_decoders(
gleam@string_tree:string_tree(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_anonymous_decoders(Sb, Ctx) ->
Operations = oaspec@codegen@types:collect_operations(Ctx),
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
),
Sb@3 = generate_anonymous_request_body_decoder(
Sb@2,
Op_id,
Operation,
Ctx
),
Sb@3
end
).
-file("src/oaspec/codegen/decoders.gleam", 212).
?DOC(" Generate inline enum decoders found in object/allOf properties.\n").
-spec generate_inline_enum_decoders(
gleam@string_tree:string_tree(),
binary(),
oaspec@openapi@schema:schema_ref(),
oaspec@codegen@context:context()
) -> gleam@string_tree:string_tree().
generate_inline_enum_decoders(Sb, Parent_name, Schema_ref, Ctx) ->
Props = case Schema_ref of
{inline, {object_schema, _, Properties, _, _, _, _}} ->
maps:to_list(Properties);
{inline, {all_of_schema, _, Schemas}} ->
Merged = gleam@list:fold(
Schemas,
maps:new(),
fun(Acc, S_ref) -> case S_ref of
{inline, {object_schema, _, Properties@1, _, _, _, _}} ->
maps:merge(Acc, Properties@1);
{reference, _} ->
case oaspec@openapi@resolver:resolve_schema_ref(
S_ref,
erlang:element(2, Ctx)
) of
{ok,
{object_schema, _, Properties@2, _, _, _, _}} ->
maps:merge(Acc, Properties@2);
_ ->
Acc
end;
_ ->
Acc
end end
),
maps:to_list(Merged);
_ ->
[]
end,
gleam@list:fold(
Props,
Sb,
fun(Sb@1, Entry) ->
{Prop_name, Prop_ref} = Entry,
case Prop_ref of
{inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] ->
Enum_name = <<(oaspec@util@naming:schema_to_type_name(
Parent_name
))/binary,
(oaspec@util@naming:schema_to_type_name(Prop_name))/binary>>,
generate_decoder(Sb@1, Enum_name, Prop_ref, Ctx);
_ ->
Sb@1
end
end
).
-file("src/oaspec/codegen/decoders.gleam", 33).
?DOC(" Generate JSON decoders for all component schemas and anonymous types.\n").
-spec generate_decoders(oaspec@codegen@context:context()) -> binary().
generate_decoders(Ctx) ->
Schemas = case erlang:element(5, erlang:element(2, Ctx)) of
{some, Components} ->
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
);
none ->
[]
end,
Needs_option = gleam@list:any(
Schemas,
fun(Entry) ->
{_, Schema_ref} = Entry,
oaspec@codegen@types:schema_has_optional_fields(Schema_ref, Ctx)
end
),
Needs_types = gleam@list:any(
Schemas,
fun(Entry@1) ->
{_, Schema_ref@1} = Entry@1,
case Schema_ref@1 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 = [<<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>],
Base_imports@1 = case Needs_types of
true ->
lists:append(
Base_imports,
[<<(erlang:element(5, erlang:element(3, Ctx)))/binary,
"/types"/utf8>>]
);
false ->
Base_imports
end,
Imports = case Needs_option of
true ->
lists:append(Base_imports@1, [<<"gleam/option"/utf8>>]);
false ->
Base_imports@1
end,
Sb = begin
_pipe = oaspec@util@string_extra:file_header(<<"0.3.0"/utf8>>),
oaspec@util@string_extra:imports(_pipe, Imports)
end,
Schemas@1 = case erlang:element(5, erlang:element(2, Ctx)) of
{some, Components@1} ->
gleam@list:sort(
maps:to_list(erlang:element(2, Components@1)),
fun(A@1, B@1) ->
gleam@string:compare(
erlang:element(1, A@1),
erlang:element(1, B@1)
)
end
);
none ->
[]
end,
Sb@2 = gleam@list:fold(
Schemas@1,
Sb,
fun(Sb@1, Entry@2) ->
{Name, Schema_ref@2} = Entry@2,
generate_inline_enum_decoders(Sb@1, Name, Schema_ref@2, Ctx)
end
),
Sb@4 = gleam@list:fold(
Schemas@1,
Sb@2,
fun(Sb@3, Entry@3) ->
{Name@1, Schema_ref@3} = Entry@3,
generate_decoder(Sb@3, Name@1, Schema_ref@3, Ctx)
end
),
Sb@5 = generate_anonymous_decoders(Sb@4, Ctx),
oaspec@util@string_extra:to_string(Sb@5).
-file("src/oaspec/codegen/decoders.gleam", 18).
?DOC(" Generate decoder and encoder modules.\n").
-spec generate(oaspec@codegen@context:context()) -> list(oaspec@codegen@context:generated_file()).
generate(Ctx) ->
Decode_content = generate_decoders(Ctx),
Encode_content = generate_encoders(Ctx),
[{generated_file, <<"decode.gleam"/utf8>>, Decode_content},
{generated_file, <<"encode.gleam"/utf8>>, Encode_content}].