-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", 893). ?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", 914). ?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>> ), <>; {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", 948). ?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", 1503). ?DOC( " Convert a SchemaRef to a json.Json encoder function reference.\n" " Used for json.nullable(value, ) and json.array(list, ).\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", 1466). ?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>>, <<<<<>/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", 1113). ?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 = <>, case Schema_ref of {inline, {object_schema, _, Properties, Required, Additional_properties, Additional_properties_untyped, _}} -> Sb@1 = begin _pipe = Sb, 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>> ) end, Has_ap = gleam@option:is_some(Additional_properties) orelse Additional_properties_untyped, Sb@2 = case Has_ap of true -> _pipe@1 = Sb@1, oaspec@util@string_extra:indent( _pipe@1, 1, <<"let base_props = ["/utf8>> ); false -> _pipe@2 = Sb@1, oaspec@util@string_extra:indent( _pipe@2, 1, <<"json.object(["/utf8>> ) end, Props = maps:to_list(Properties), Sb@4 = gleam@list:index_fold( Props, Sb@2, fun(Sb@3, 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@3 = Sb@3, oaspec@util@string_extra:indent( _pipe@3, 2, <<<<<<<<<<"#(\""/utf8, Prop_name/binary>>/binary, "\", "/utf8>>/binary, Encoder_expr/binary>>/binary, ")"/utf8>>/binary, Trailing/binary>> ); false -> _pipe@4 = Sb@3, oaspec@util@string_extra:indent( _pipe@4, 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@5 = case {Additional_properties, Additional_properties_untyped} of {{some, Ap_ref}, _} -> Inner_encoder_fn = schema_ref_to_json_encoder_fn( Ap_ref, Name, <<"additional_properties"/utf8>>, Ctx ), _pipe@5 = Sb@4, _pipe@6 = oaspec@util@string_extra:indent( _pipe@5, 1, <<"]"/utf8>> ), _pipe@7 = oaspec@util@string_extra:indent( _pipe@6, 1, <<<<"let extra_props = dict.to_list(value.additional_properties) |> list.map(fn(entry) { let #(k, v) = entry; #(k, "/utf8, Inner_encoder_fn/binary>>/binary, "(v)) })"/utf8>> ), oaspec@util@string_extra:indent( _pipe@7, 1, <<"json.object(list.append(base_props, extra_props))"/utf8>> ); {none, true} -> _pipe@8 = Sb@4, _pipe@9 = oaspec@util@string_extra:indent( _pipe@8, 1, <<"]"/utf8>> ), oaspec@util@string_extra:indent( _pipe@9, 1, <<"json.object(base_props)"/utf8>> ); {none, false} -> _pipe@10 = Sb@4, oaspec@util@string_extra:indent(_pipe@10, 1, <<"])"/utf8>>) end, Sb@6 = begin _pipe@11 = Sb@5, _pipe@12 = oaspec@util@string_extra:line(_pipe@11, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@12) end, Sb@7 = begin _pipe@13 = Sb@6, _pipe@14 = oaspec@util@string_extra:line( _pipe@13, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: types."/utf8>>/binary, Type_name/binary>>/binary, ") -> String {"/utf8>> ), _pipe@15 = oaspec@util@string_extra:indent( _pipe@14, 1, < json.to_string()"/utf8>> ), _pipe@16 = oaspec@util@string_extra:line(_pipe@15, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@16) end, Sb@7; {inline, {string_schema, _, _, Enum_values, _, _, _, _}} when Enum_values =/= [] -> Sb@8 = begin _pipe@17 = Sb, _pipe@18 = oaspec@util@string_extra:line( _pipe@17, <<<<<<<<"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@18, 1, <<"let str = case value {"/utf8>> ) end, Sb@10 = gleam@list:fold( Enum_values, Sb@8, fun(Sb@9, Value) -> Variant = oaspec@util@naming:schema_to_type_name( <<<>/binary, Value/binary>> ), _pipe@19 = Sb@9, oaspec@util@string_extra:indent( _pipe@19, 2, <<<<<<<<"types."/utf8, Variant/binary>>/binary, " -> \""/utf8>>/binary, Value/binary>>/binary, "\""/utf8>> ) end ), Sb@11 = begin _pipe@20 = Sb@10, _pipe@21 = oaspec@util@string_extra:indent( _pipe@20, 1, <<"}"/utf8>> ), _pipe@22 = oaspec@util@string_extra:indent( _pipe@21, 1, <<"json.string(str)"/utf8>> ), _pipe@23 = oaspec@util@string_extra:line(_pipe@22, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@23) end, Sb@12 = begin _pipe@24 = Sb@11, _pipe@25 = oaspec@util@string_extra:line( _pipe@24, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: types."/utf8>>/binary, Type_name/binary>>/binary, ") -> String {"/utf8>> ), _pipe@26 = oaspec@util@string_extra:indent( _pipe@25, 1, < json.to_string()"/utf8>> ), _pipe@27 = oaspec@util@string_extra:line(_pipe@26, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@27) end, To_string_fn_name = <>, Sb@13 = begin _pipe@28 = Sb@12, _pipe@29 = oaspec@util@string_extra:line( _pipe@28, <<<<<<<<"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@29, 1, <<"case value {"/utf8>> ) end, Sb@15 = gleam@list:fold( Enum_values, Sb@13, fun(Sb@14, Value@1) -> Variant@1 = oaspec@util@naming:schema_to_type_name( <<<>/binary, Value@1/binary>> ), _pipe@30 = Sb@14, oaspec@util@string_extra:indent( _pipe@30, 2, <<<<<<<<"types."/utf8, Variant@1/binary>>/binary, " -> \""/utf8>>/binary, Value@1/binary>>/binary, "\""/utf8>> ) end ), Sb@16 = begin _pipe@31 = Sb@15, _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@16; {inline, {all_of_schema, Description, Schemas}} -> Merged = oaspec@codegen@types:merge_allof_schemas(Schemas, Ctx), Merged_schema = {inline, {object_schema, Description, erlang:element(2, Merged), erlang:element(3, Merged), erlang:element(4, Merged), erlang:element(5, Merged), 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@17 = begin _pipe@34 = Sb, _pipe@35 = oaspec@util@string_extra:line( _pipe@34, <<<<<<<<"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@35, 1, <<"case value {"/utf8>> ) end, Sb@19 = gleam@list:fold( Schemas@1, Sb@17, fun(Sb@18, 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 = <>, Inner_encoder = <<<<"encode_"/utf8, (oaspec@util@naming:to_snake_case( Ref_name ))/binary>>/binary, "_json"/utf8>>, _pipe@36 = Sb@18, oaspec@util@string_extra:indent( _pipe@36, 2, <<<<<<<<"types."/utf8, Variant_name/binary>>/binary, "(inner) -> "/utf8>>/binary, Inner_encoder/binary>>/binary, "(inner)"/utf8>> ); _ -> Sb@18 end end ), Sb@20 = begin _pipe@37 = Sb@19, _pipe@38 = oaspec@util@string_extra:indent( _pipe@37, 1, <<"}"/utf8>> ), _pipe@39 = oaspec@util@string_extra:line( _pipe@38, <<"}"/utf8>> ), oaspec@util@string_extra:blank_line(_pipe@39) end, Sb@21 = begin _pipe@40 = Sb@20, _pipe@41 = oaspec@util@string_extra:line( _pipe@40, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: types."/utf8>>/binary, Type_name/binary>>/binary, ") -> String {"/utf8>> ), _pipe@42 = oaspec@util@string_extra:indent( _pipe@41, 1, < json.to_string()"/utf8>> ), _pipe@43 = oaspec@util@string_extra:line( _pipe@42, <<"}"/utf8>> ), oaspec@util@string_extra:blank_line(_pipe@43) end, Sb@21 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@17 = begin _pipe@34 = Sb, _pipe@35 = oaspec@util@string_extra:line( _pipe@34, <<<<<<<<"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@35, 1, <<"case value {"/utf8>> ) end, Sb@19 = gleam@list:fold( Schemas@1, Sb@17, fun(Sb@18, 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 = <>, Inner_encoder = <<<<"encode_"/utf8, (oaspec@util@naming:to_snake_case( Ref_name ))/binary>>/binary, "_json"/utf8>>, _pipe@36 = Sb@18, oaspec@util@string_extra:indent( _pipe@36, 2, <<<<<<<<"types."/utf8, Variant_name/binary>>/binary, "(inner) -> "/utf8>>/binary, Inner_encoder/binary>>/binary, "(inner)"/utf8>> ); _ -> Sb@18 end end ), Sb@20 = begin _pipe@37 = Sb@19, _pipe@38 = oaspec@util@string_extra:indent( _pipe@37, 1, <<"}"/utf8>> ), _pipe@39 = oaspec@util@string_extra:line( _pipe@38, <<"}"/utf8>> ), oaspec@util@string_extra:blank_line(_pipe@39) end, Sb@21 = begin _pipe@40 = Sb@20, _pipe@41 = oaspec@util@string_extra:line( _pipe@40, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: types."/utf8>>/binary, Type_name/binary>>/binary, ") -> String {"/utf8>> ), _pipe@42 = oaspec@util@string_extra:indent( _pipe@41, 1, < json.to_string()"/utf8>> ), _pipe@43 = oaspec@util@string_extra:line( _pipe@42, <<"}"/utf8>> ), oaspec@util@string_extra:blank_line(_pipe@43) end, Sb@21 end; {inline, {string_schema, _, _, [], _, _, _, _}} -> _pipe@44 = Sb, _pipe@45 = oaspec@util@string_extra:line( _pipe@44, <<<<"pub fn "/utf8, Json_fn_name/binary>>/binary, "(value: String) -> json.Json {"/utf8>> ), _pipe@46 = oaspec@util@string_extra:indent( _pipe@45, 1, <<"json.string(value)"/utf8>> ), _pipe@47 = oaspec@util@string_extra:line(_pipe@46, <<"}"/utf8>>), _pipe@48 = oaspec@util@string_extra:blank_line(_pipe@47), _pipe@49 = oaspec@util@string_extra:line( _pipe@48, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: String) -> String {"/utf8>> ), _pipe@50 = oaspec@util@string_extra:indent( _pipe@49, 1, < json.to_string()"/utf8>> ), _pipe@51 = oaspec@util@string_extra:line(_pipe@50, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@51); {inline, {integer_schema, _, _, _, _, _}} -> _pipe@52 = Sb, _pipe@53 = oaspec@util@string_extra:line( _pipe@52, <<<<"pub fn "/utf8, Json_fn_name/binary>>/binary, "(value: Int) -> json.Json {"/utf8>> ), _pipe@54 = oaspec@util@string_extra:indent( _pipe@53, 1, <<"json.int(value)"/utf8>> ), _pipe@55 = oaspec@util@string_extra:line(_pipe@54, <<"}"/utf8>>), _pipe@56 = oaspec@util@string_extra:blank_line(_pipe@55), _pipe@57 = oaspec@util@string_extra:line( _pipe@56, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: Int) -> String {"/utf8>> ), _pipe@58 = oaspec@util@string_extra:indent( _pipe@57, 1, < json.to_string()"/utf8>> ), _pipe@59 = oaspec@util@string_extra:line(_pipe@58, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@59); {inline, {number_schema, _, _, _, _, _}} -> _pipe@60 = Sb, _pipe@61 = oaspec@util@string_extra:line( _pipe@60, <<<<"pub fn "/utf8, Json_fn_name/binary>>/binary, "(value: Float) -> json.Json {"/utf8>> ), _pipe@62 = oaspec@util@string_extra:indent( _pipe@61, 1, <<"json.float(value)"/utf8>> ), _pipe@63 = oaspec@util@string_extra:line(_pipe@62, <<"}"/utf8>>), _pipe@64 = oaspec@util@string_extra:blank_line(_pipe@63), _pipe@65 = oaspec@util@string_extra:line( _pipe@64, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: Float) -> String {"/utf8>> ), _pipe@66 = oaspec@util@string_extra:indent( _pipe@65, 1, < json.to_string()"/utf8>> ), _pipe@67 = oaspec@util@string_extra:line(_pipe@66, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@67); {inline, {boolean_schema, _, _}} -> _pipe@68 = Sb, _pipe@69 = oaspec@util@string_extra:line( _pipe@68, <<<<"pub fn "/utf8, Json_fn_name/binary>>/binary, "(value: Bool) -> json.Json {"/utf8>> ), _pipe@70 = oaspec@util@string_extra:indent( _pipe@69, 1, <<"json.bool(value)"/utf8>> ), _pipe@71 = oaspec@util@string_extra:line(_pipe@70, <<"}"/utf8>>), _pipe@72 = oaspec@util@string_extra:blank_line(_pipe@71), _pipe@73 = oaspec@util@string_extra:line( _pipe@72, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(value: Bool) -> String {"/utf8>> ), _pipe@74 = oaspec@util@string_extra:indent( _pipe@73, 1, < json.to_string()"/utf8>> ), _pipe@75 = oaspec@util@string_extra:line(_pipe@74, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@75); _ -> Sb end. -file("src/oaspec/codegen/decoders.gleam", 1031). ?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", 1084). ?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", 1071). ?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", 964). ?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 ), Needs_typed_dict = gleam@list:any( Schemas, fun(Entry@1) -> {_, Schema_ref@1} = Entry@1, case Schema_ref@1 of {inline, {object_schema, _, _, _, {some, _}, _, _}} -> true; _ -> false end end ), Base_imports = case Needs_typed_dict of true -> [<<"gleam/dict"/utf8>>, <<"gleam/json"/utf8>>, <<"gleam/list"/utf8>>]; false -> [<<"gleam/json"/utf8>>] end, 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.4.0"/utf8>>), oaspec@util@string_extra:imports(_pipe, Imports) end, Sb@2 = gleam@list:fold( Schemas, Sb, fun(Sb@1, Entry@2) -> {Name, Schema_ref@2} = Entry@2, generate_inline_enum_encoders(Sb@1, Name, Schema_ref@2, Ctx) end ), Sb@4 = gleam@list:fold( Schemas, Sb@2, fun(Sb@3, Entry@3) -> {Name@1, Schema_ref@3} = Entry@3, generate_encoder(Sb@3, Name@1, Schema_ref@3, Ctx) end ), Sb@5 = generate_anonymous_encoders(Sb@4, Ctx), oaspec@util@string_extra:to_string(Sb@5). -file("src/oaspec/codegen/decoders.gleam", 1537). ?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", 704). ?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 = <>, 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 = <>, 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", 260). ?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, Additional_properties, Additional_properties_untyped, 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 ), Known_keys_expr = case gleam@list:is_empty(Props) of true -> <<"[]"/utf8>>; false -> <<<<"["/utf8, (oaspec@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, Additional_properties_untyped} of {{some, Ap_ref}, _} -> Inner_decoder = schema_ref_to_decoder( Ap_ref, Name, <<"additional_properties"/utf8>>, Ctx ), _pipe@4 = Sb@4, _pipe@5 = oaspec@util@string_extra:indent( _pipe@4, 1, <<"use all_props <- decode.then(decode.dict(decode.string, dynamic.dynamic))"/utf8>> ), _pipe@6 = oaspec@util@string_extra:indent( _pipe@5, 1, <<<<"let extra_props = dict.drop(all_props, "/utf8, Known_keys_expr/binary>>/binary, ")"/utf8>> ), _pipe@7 = oaspec@util@string_extra:indent( _pipe@6, 1, <<"let additional_properties_result = dict.fold(extra_props, Ok(dict.new()), fn(acc, k, v) {"/utf8>> ), _pipe@8 = oaspec@util@string_extra:indent( _pipe@7, 2, <<"case acc {"/utf8>> ), _pipe@9 = oaspec@util@string_extra:indent( _pipe@8, 3, <<"Ok(decoded_acc) ->"/utf8>> ), _pipe@10 = oaspec@util@string_extra:indent( _pipe@9, 4, <<<<"case decode.run(v, "/utf8, Inner_decoder/binary>>/binary, ") {"/utf8>> ), _pipe@11 = oaspec@util@string_extra:indent( _pipe@10, 5, <<"Ok(decoded) -> Ok(dict.insert(decoded_acc, k, decoded))"/utf8>> ), _pipe@12 = oaspec@util@string_extra:indent( _pipe@11, 5, <<"Error(_) -> Error(Nil)"/utf8>> ), _pipe@13 = oaspec@util@string_extra:indent( _pipe@12, 4, <<"}"/utf8>> ), _pipe@14 = oaspec@util@string_extra:indent( _pipe@13, 3, <<"Error(_) -> Error(Nil)"/utf8>> ), _pipe@15 = oaspec@util@string_extra:indent( _pipe@14, 2, <<"}"/utf8>> ), _pipe@16 = oaspec@util@string_extra:indent( _pipe@15, 1, <<"})"/utf8>> ), _pipe@17 = oaspec@util@string_extra:indent( _pipe@16, 1, <<"use additional_properties <- decode.then(case additional_properties_result {"/utf8>> ), _pipe@18 = oaspec@util@string_extra:indent( _pipe@17, 2, <<"Ok(decoded) -> decode.success(decoded)"/utf8>> ), _pipe@19 = oaspec@util@string_extra:indent( _pipe@18, 2, <<"Error(_) -> decode.failure(dict.new(), \"additionalProperties\")"/utf8>> ), oaspec@util@string_extra:indent(_pipe@19, 1, <<"})"/utf8>>); {none, true} -> _pipe@20 = Sb@4, _pipe@21 = oaspec@util@string_extra:indent( _pipe@20, 1, <<"use all_props <- decode.then(decode.dict(decode.string, dynamic.dynamic))"/utf8>> ), oaspec@util@string_extra:indent( _pipe@21, 1, <<<<"let additional_properties = dict.drop(all_props, "/utf8, Known_keys_expr/binary>>/binary, ")"/utf8>> ); {none, false} -> Sb@4 end, Param_names = gleam@list:map( Props, fun(Entry@2) -> {Prop_name@2, _} = Entry@2, Field_name@1 = oaspec@util@naming:to_snake_case(Prop_name@2), <<<>/binary, Field_name@1/binary>> end ), Param_names@1 = case {Additional_properties, Additional_properties_untyped} of {{some, _}, _} -> lists:append( Param_names, [<<"additional_properties: additional_properties"/utf8>>] ); {none, true} -> lists:append( Param_names, [<<"additional_properties: additional_properties"/utf8>>] ); {none, false} -> Param_names end, Sb@6 = begin _pipe@22 = Sb@5, oaspec@util@string_extra:indent( _pipe@22, 1, <<<<<<<<"decode.success(types."/utf8, Type_name/binary>>/binary, "("/utf8>>/binary, (oaspec@util@string_extra:join_with( Param_names@1, <<", "/utf8>> ))/binary>>/binary, "))"/utf8>> ) end, Sb@7 = begin _pipe@23 = Sb@6, _pipe@24 = oaspec@util@string_extra:line(_pipe@23, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@24) end, Sb@8 = begin _pipe@25 = Sb@7, _pipe@26 = oaspec@util@string_extra:line( _pipe@25, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(types."/utf8>>/binary, Type_name/binary>>/binary, ", json.DecodeError) {"/utf8>> ), _pipe@27 = oaspec@util@string_extra:indent( _pipe@26, 1, <<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary, "())"/utf8>> ), _pipe@28 = oaspec@util@string_extra:line(_pipe@27, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@28) end, List_fn_name = <>, List_decoder_fn_name = <>, Sb@9 = begin _pipe@29 = Sb@8, _pipe@30 = oaspec@util@string_extra:line( _pipe@29, <<<<<<<<"pub fn "/utf8, List_decoder_fn_name/binary>>/binary, "() -> decode.Decoder(List(types."/utf8>>/binary, Type_name/binary>>/binary, ")) {"/utf8>> ), _pipe@31 = oaspec@util@string_extra:indent( _pipe@30, 1, <<<<"decode.list("/utf8, Decoder_fn_name/binary>>/binary, "())"/utf8>> ), _pipe@32 = oaspec@util@string_extra:line(_pipe@31, <<"}"/utf8>>), _pipe@33 = oaspec@util@string_extra:blank_line(_pipe@32), _pipe@34 = oaspec@util@string_extra:line( _pipe@33, <<<<<<<<"pub fn "/utf8, List_fn_name/binary>>/binary, "(json_string: String) -> Result(List(types."/utf8>>/binary, Type_name/binary>>/binary, "), json.DecodeError) {"/utf8>> ), _pipe@35 = oaspec@util@string_extra:indent( _pipe@34, 1, <<<<"json.parse(json_string, "/utf8, List_decoder_fn_name/binary>>/binary, "())"/utf8>> ), _pipe@36 = oaspec@util@string_extra:line(_pipe@35, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@36) end, _ = Nullable, Sb@9; {inline, {string_schema, Description@1, _, Enum_values, _, _, _, _}} when Enum_values =/= [] -> Sb@10 = maybe_doc_comment(Sb, Description@1), Sb@11 = begin _pipe@37 = Sb@10, _pipe@38 = oaspec@util@string_extra:line( _pipe@37, <<<<<<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary, "() -> decode.Decoder(types."/utf8>>/binary, Type_name/binary>>/binary, ") {"/utf8>> ), _pipe@39 = oaspec@util@string_extra:indent( _pipe@38, 1, <<"use value <- decode.then(decode.string)"/utf8>> ), oaspec@util@string_extra:indent( _pipe@39, 1, <<"case value {"/utf8>> ) end, Sb@13 = gleam@list:fold( Enum_values, Sb@11, fun(Sb@12, Value) -> Variant = oaspec@util@naming:schema_to_type_name( <<<>/binary, Value/binary>> ), _pipe@40 = Sb@12, oaspec@util@string_extra:indent( _pipe@40, 2, <<<<<<<<"\""/utf8, Value/binary>>/binary, "\" -> decode.success(types."/utf8>>/binary, Variant/binary>>/binary, ")"/utf8>> ) end ), Sb@14 = begin _pipe@41 = Sb@13, _pipe@42 = oaspec@util@string_extra:indent( _pipe@41, 2, <<<<<<<<"_ -> decode.failure(types."/utf8, (oaspec@util@naming:schema_to_type_name( <<<>/binary, ((case Enum_values of [First | _] -> First; [] -> <<"unknown"/utf8>> end))/binary>> ))/binary>>/binary, ", \""/utf8>>/binary, Type_name/binary>>/binary, "\")"/utf8>> ), _pipe@43 = oaspec@util@string_extra:indent( _pipe@42, 1, <<"}"/utf8>> ), _pipe@44 = oaspec@util@string_extra:line(_pipe@43, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@44) end, Sb@15 = begin _pipe@45 = Sb@14, _pipe@46 = oaspec@util@string_extra:line( _pipe@45, <<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(types."/utf8>>/binary, Type_name/binary>>/binary, ", json.DecodeError) {"/utf8>> ), _pipe@47 = oaspec@util@string_extra:indent( _pipe@46, 1, <<<<"json.parse(json_string, "/utf8, Decoder_fn_name/binary>>/binary, "())"/utf8>> ), _pipe@48 = oaspec@util@string_extra:line(_pipe@47, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@48) end, Sb@15; {inline, {all_of_schema, Description@2, Schemas}} -> Merged = oaspec@codegen@types:merge_allof_schemas(Schemas, Ctx), Merged_schema = {inline, {object_schema, Description@2, erlang:element(2, Merged), erlang:element(3, Merged), erlang:element(4, Merged), erlang:element(5, Merged), 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@16 = begin _pipe@49 = Sb, _pipe@50 = oaspec@util@string_extra:line( _pipe@49, <<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary, "() -> decode.Decoder(String) {"/utf8>> ), _pipe@51 = oaspec@util@string_extra:indent( _pipe@50, 1, <<"decode.string"/utf8>> ), _pipe@52 = oaspec@util@string_extra:line(_pipe@51, <<"}"/utf8>>), _pipe@53 = oaspec@util@string_extra:blank_line(_pipe@52), _pipe@54 = oaspec@util@string_extra:line( _pipe@53, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(String, json.DecodeError) {"/utf8>> ), _pipe@55 = oaspec@util@string_extra:indent( _pipe@54, 1, <<"json.parse(json_string, decode.string)"/utf8>> ), _pipe@56 = oaspec@util@string_extra:line(_pipe@55, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@56) end, Sb@16; {inline, {integer_schema, _, _, _, _, _}} -> Sb@17 = begin _pipe@57 = Sb, _pipe@58 = oaspec@util@string_extra:line( _pipe@57, <<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary, "() -> decode.Decoder(Int) {"/utf8>> ), _pipe@59 = oaspec@util@string_extra:indent( _pipe@58, 1, <<"decode.int"/utf8>> ), _pipe@60 = oaspec@util@string_extra:line(_pipe@59, <<"}"/utf8>>), _pipe@61 = oaspec@util@string_extra:blank_line(_pipe@60), _pipe@62 = oaspec@util@string_extra:line( _pipe@61, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(Int, json.DecodeError) {"/utf8>> ), _pipe@63 = oaspec@util@string_extra:indent( _pipe@62, 1, <<"json.parse(json_string, decode.int)"/utf8>> ), _pipe@64 = oaspec@util@string_extra:line(_pipe@63, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@64) end, Sb@17; {inline, {number_schema, _, _, _, _, _}} -> Sb@18 = begin _pipe@65 = Sb, _pipe@66 = oaspec@util@string_extra:line( _pipe@65, <<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary, "() -> decode.Decoder(Float) {"/utf8>> ), _pipe@67 = oaspec@util@string_extra:indent( _pipe@66, 1, <<"decode.float"/utf8>> ), _pipe@68 = oaspec@util@string_extra:line(_pipe@67, <<"}"/utf8>>), _pipe@69 = oaspec@util@string_extra:blank_line(_pipe@68), _pipe@70 = oaspec@util@string_extra:line( _pipe@69, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(Float, json.DecodeError) {"/utf8>> ), _pipe@71 = oaspec@util@string_extra:indent( _pipe@70, 1, <<"json.parse(json_string, decode.float)"/utf8>> ), _pipe@72 = oaspec@util@string_extra:line(_pipe@71, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@72) end, Sb@18; {inline, {boolean_schema, _, _}} -> Sb@19 = begin _pipe@73 = Sb, _pipe@74 = oaspec@util@string_extra:line( _pipe@73, <<<<"pub fn "/utf8, Decoder_fn_name/binary>>/binary, "() -> decode.Decoder(Bool) {"/utf8>> ), _pipe@75 = oaspec@util@string_extra:indent( _pipe@74, 1, <<"decode.bool"/utf8>> ), _pipe@76 = oaspec@util@string_extra:line(_pipe@75, <<"}"/utf8>>), _pipe@77 = oaspec@util@string_extra:blank_line(_pipe@76), _pipe@78 = oaspec@util@string_extra:line( _pipe@77, <<<<"pub fn "/utf8, Fn_name/binary>>/binary, "(json_string: String) -> Result(Bool, json.DecodeError) {"/utf8>> ), _pipe@79 = oaspec@util@string_extra:indent( _pipe@78, 1, <<"json.parse(json_string, decode.bool)"/utf8>> ), _pipe@80 = oaspec@util@string_extra:line(_pipe@79, <<"}"/utf8>>), oaspec@util@string_extra:blank_line(_pipe@80) end, Sb@19; _ -> Sb end. -file("src/oaspec/codegen/decoders.gleam", 207). ?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", 146). ?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, (oaspec@util@http: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", 177). ?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", 132). ?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", 220). ?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", 34). ?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_dict = gleam@list:any( Schemas, fun(Entry@1) -> {_, Schema_ref@1} = Entry@1, oaspec@codegen@types:schema_has_additional_properties( Schema_ref@1, Ctx ) end ), Needs_dynamic = gleam@list:any( Schemas, fun(Entry@2) -> {_, Schema_ref@2} = Entry@2, oaspec@codegen@types:schema_has_additional_properties( Schema_ref@2, Ctx ) end ), Needs_types = gleam@list:any( Schemas, fun(Entry@3) -> {_, Schema_ref@3} = Entry@3, case Schema_ref@3 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, Needs_dynamic} of {true, true} -> [<<"gleam/dict"/utf8>>, <<"gleam/dynamic"/utf8>>, <<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>]; {true, false} -> [<<"gleam/dict"/utf8>>, <<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>]; {false, true} -> [<<"gleam/dynamic"/utf8>>, <<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>]; {false, false} -> [<<"gleam/dynamic/decode"/utf8>>, <<"gleam/json"/utf8>>] end, 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.4.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@4) -> {Name, Schema_ref@4} = Entry@4, generate_inline_enum_decoders(Sb@1, Name, Schema_ref@4, Ctx) end ), Sb@4 = gleam@list:fold( Schemas@1, Sb@2, fun(Sb@3, Entry@5) -> {Name@1, Schema_ref@5} = Entry@5, generate_decoder(Sb@3, Name@1, Schema_ref@5, Ctx) end ), Sb@5 = generate_anonymous_decoders(Sb@4, Ctx), oaspec@util@string_extra:to_string(Sb@5). -file("src/oaspec/codegen/decoders.gleam", 19). ?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}].