-module(mcp_toolkit@core@json_schema). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/mcp_toolkit/core/json_schema.gleam"). -export([codegen/0, root_name/2, generate_encoders/2, generate_decoders/2, generate/2, decoder/1, decode_object_schema/1, object_schema_to_json/1, to_json/1]). -export_type([root_schema/0, type/0, schema/0, object_schema/0, generator/0, out/0, codegen_error/0, property_data_name/0]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " \n" "\n" " \n" ). -type root_schema() :: {root_schema, list({binary(), schema()}), schema()}. -type type() :: boolean | string | number | integer | array_type | object_type | null. -type schema() :: {empty, list({binary(), gleam@dynamic:dynamic_()})} | {type, boolean(), list({binary(), gleam@dynamic:dynamic_()}), type()} | {enum, boolean(), list({binary(), gleam@dynamic:dynamic_()}), list(binary())} | {object, boolean(), list({binary(), gleam@dynamic:dynamic_()}), object_schema()} | {array, boolean(), list({binary(), gleam@dynamic:dynamic_()}), schema()} | {ref, boolean(), list({binary(), gleam@dynamic:dynamic_()}), binary()} | {one_of, boolean(), list({binary(), gleam@dynamic:dynamic_()}), list(schema())} | {all_of, boolean(), list({binary(), gleam@dynamic:dynamic_()}), list(schema())} | {any_of, boolean(), list({binary(), gleam@dynamic:dynamic_()}), list(schema())} | {'not', boolean(), list({binary(), gleam@dynamic:dynamic_()}), schema()}. -type object_schema() :: {object_schema, list({binary(), schema()}), list(binary()), gleam@option:option(schema()), list({binary(), schema()})}. -opaque generator() :: {generator, boolean(), boolean(), boolean(), boolean(), boolean(), boolean(), gleam@dict:dict(binary(), binary()), gleam@dict:dict(binary(), binary()), binary(), gleam@set:set(binary())}. -type out() :: {out, binary(), binary()}. -type codegen_error() :: cannot_convert_empty_to_json_error | empty_enum_error | {duplicate_property_error, binary(), binary(), binary()} | {duplicate_constructor_error, binary()} | {duplicate_type_error, binary()} | {duplicate_function_error, binary()}. -type property_data_name() :: property_data_none | property_data_direct | {property_data_access, binary()}. -file("src/mcp_toolkit/core/json_schema.gleam", 219). -spec type_to_json(type()) -> gleam@json:json(). type_to_json(T) -> gleam@json:string(case T of boolean -> <<"boolean"/utf8>>; string -> <<"string"/utf8>>; number -> <<"number"/utf8>>; integer -> <<"integer"/utf8>>; array_type -> <<"array"/utf8>>; object_type -> <<"object"/utf8>>; null -> <<"null"/utf8>> end). -file("src/mcp_toolkit/core/json_schema.gleam", 294). -spec key_decoder( gleam@dict:dict(binary(), gleam@dynamic:dynamic_()), binary(), fun((gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_())) -> {ok, VHA} | {error, list(gleam@dynamic@decode:decode_error())}) ) -> {ok, fun(() -> {ok, VHA} | {error, list(gleam@dynamic@decode:decode_error())})} | {error, nil}. key_decoder(Data, Key, Constructor) -> case gleam_stdlib:map_get(Data, Key) of {ok, Value} -> {ok, fun() -> Constructor(Value, Data) end}; {error, E} -> {error, E} end. -file("src/mcp_toolkit/core/json_schema.gleam", 528). -spec get_metadata(gleam@dict:dict(binary(), gleam@dynamic:dynamic_())) -> {ok, list({binary(), gleam@dynamic:dynamic_()})} | {error, list(gleam@dynamic@decode:decode_error())}. get_metadata(Data) -> Ignored_keys = gleam@set:from_list( [<<"type"/utf8>>, <<"enum"/utf8>>, <<"$ref"/utf8>>, <<"items"/utf8>>, <<"properties"/utf8>>, <<"required"/utf8>>, <<"additionalProperties"/utf8>>, <<"patternProperties"/utf8>>, <<"oneOf"/utf8>>, <<"anyOf"/utf8>>, <<"allOf"/utf8>>, <<"not"/utf8>>, <<"$defs"/utf8>>, <<"definitions"/utf8>>, <<"nullable"/utf8>>] ), Extract_metadata = fun(Acc, Key, Value) -> case gleam@set:contains(Ignored_keys, Key) of true -> Acc; false -> [{Key, Value} | Acc] end end, Metadata = gleam@dict:fold(Data, [], Extract_metadata), {ok, Metadata}. -file("src/mcp_toolkit/core/json_schema.gleam", 515). -spec decode_empty(gleam@dict:dict(binary(), gleam@dynamic:dynamic_())) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_empty(Data) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> {ok, {empty, Metadata}} end ). -file("src/mcp_toolkit/core/json_schema.gleam", 549). -spec get_nullable(gleam@dict:dict(binary(), gleam@dynamic:dynamic_())) -> {ok, boolean()} | {error, list(gleam@dynamic@decode:decode_error())}. get_nullable(Data) -> case gleam_stdlib:map_get(Data, <<"nullable"/utf8>>) of {ok, Data@1} -> gleam@dynamic@decode:run( Data@1, {decoder, fun gleam@dynamic@decode:decode_bool/1} ); {error, _} -> case gleam_stdlib:map_get(Data, <<"type"/utf8>>) of {ok, Type_value} -> case gleam@dynamic@decode:run( Type_value, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ) of {ok, Types} -> {ok, gleam@list:contains(Types, <<"null"/utf8>>)}; {error, _} -> {ok, false} end; {error, _} -> {ok, false} end end. -file("src/mcp_toolkit/core/json_schema.gleam", 463). -spec decode_type( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_type(Type_, Data) -> gleam@result:'try'( begin _pipe = gleam@dynamic@decode:run( Type_, {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@result:lazy_or( _pipe, fun() -> _pipe@1 = gleam@dynamic@decode:run( Type_, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ), gleam@result:map(_pipe@1, fun(Types) -> case Types of [T] -> T; _ -> <<"object"/utf8>> end end) end ) end, fun(Type_@1) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> case Type_@1 of <<"boolean"/utf8>> -> {ok, {type, Nullable, Metadata, boolean}}; <<"string"/utf8>> -> {ok, {type, Nullable, Metadata, string}}; <<"number"/utf8>> -> {ok, {type, Nullable, Metadata, number}}; <<"integer"/utf8>> -> {ok, {type, Nullable, Metadata, integer}}; <<"array"/utf8>> -> {ok, {type, Nullable, Metadata, array_type}}; <<"object"/utf8>> -> {ok, {type, Nullable, Metadata, object_type}}; <<"null"/utf8>> -> {ok, {type, Nullable, Metadata, null}}; _ -> {ok, {type, Nullable, Metadata, object_type}} end end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 495). -spec decode_enum( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_enum(Variants, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> _pipe = gleam@dynamic@decode:run( Variants, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ), gleam@result:map( _pipe, fun(_capture) -> {enum, Nullable, Metadata, _capture} end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 505). -spec decode_ref( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_ref(Ref, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> _pipe = gleam@dynamic@decode:run( Ref, {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@result:map( _pipe, fun(_capture) -> {ref, Nullable, Metadata, _capture} end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 570). -spec metadata_value_to_json(gleam@dynamic:dynamic_()) -> gleam@json:json(). metadata_value_to_json(Data) -> Decoder = gleam@dynamic@decode:one_of( gleam@dynamic@decode:map( {decoder, fun gleam@dynamic@decode:decode_string/1}, fun gleam@json:string/1 ), [gleam@dynamic@decode:map( {decoder, fun gleam@dynamic@decode:decode_int/1}, fun gleam@json:int/1 ), gleam@dynamic@decode:map( {decoder, fun gleam@dynamic@decode:decode_float/1}, fun gleam@json:float/1 ), gleam@dynamic@decode:map( {decoder, fun gleam@dynamic@decode:decode_bool/1}, fun gleam@json:bool/1 )] ), case gleam@dynamic@decode:run(Data, Decoder) of {ok, Data@1} -> Data@1; {error, _} -> gleam@json:string(gleam@string:inspect(Data)) end. -file("src/mcp_toolkit/core/json_schema.gleam", 583). -spec add_metadata( list({binary(), gleam@json:json()}), list({binary(), gleam@dynamic:dynamic_()}) ) -> list({binary(), gleam@json:json()}). add_metadata(Data, Metadata) -> gleam@list:fold( Metadata, Data, fun(Acc, Meta) -> [{erlang:element(1, Meta), metadata_value_to_json(erlang:element(2, Meta))} | Acc] end ). -file("src/mcp_toolkit/core/json_schema.gleam", 592). -spec add_nullable(list({binary(), gleam@json:json()}), boolean()) -> list({binary(), gleam@json:json()}). add_nullable(Data, Nullable) -> case Nullable of false -> Data; true -> [{<<"nullable"/utf8>>, gleam@json:bool(true)} | Data] end. -file("src/mcp_toolkit/core/json_schema.gleam", 617). -spec codegen() -> generator(). codegen() -> {generator, false, false, false, false, false, false, maps:new(), maps:new(), <<"Data"/utf8>>, gleam@set:new()}. -file("src/mcp_toolkit/core/json_schema.gleam", 632). -spec root_name(generator(), binary()) -> generator(). root_name(Gen, Root_name) -> {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), Root_name, erlang:element(11, Gen)}. -file("src/mcp_toolkit/core/json_schema.gleam", 636). -spec generate_encoders(generator(), boolean()) -> generator(). generate_encoders(Gen, X) -> {generator, erlang:element(2, Gen), X, erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)}. -file("src/mcp_toolkit/core/json_schema.gleam", 640). -spec generate_decoders(generator(), boolean()) -> generator(). generate_decoders(Gen, X) -> {generator, X, erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)}. -file("src/mcp_toolkit/core/json_schema.gleam", 763). -spec type_name(schema(), binary()) -> binary(). type_name(Schema, Name) -> Nullable@1 = case Schema of {empty, _} -> false; {'not', Nullable, _, _} -> Nullable; {array, Nullable, _, _} -> Nullable; {enum, Nullable, _, _} -> Nullable; {one_of, Nullable, _, _} -> Nullable; {any_of, Nullable, _, _} -> Nullable; {all_of, Nullable, _, _} -> Nullable; {object, Nullable, _, _} -> Nullable; {ref, Nullable, _, _} -> Nullable; {type, Nullable, _, _} -> Nullable end, Name@1 = case Schema of {enum, _, _, _} -> Name; {object, _, _, _} -> Name; {ref, _, _, Ref} -> case gleam@string:split(Ref, <<"/"/utf8>>) of [<<"#"/utf8>>, <<"definitions"/utf8>>, Def_name] -> justin:pascal_case(Def_name); [<<"#"/utf8>>, <<"$defs"/utf8>>, Def_name@1] -> justin:pascal_case(Def_name@1); _ -> <<"Unknown"/utf8>> end; {array, _, _, Items} -> <<<<"List("/utf8, (type_name(Items, <>))/binary>>/binary, ")"/utf8>>; {empty, _} -> <<"dynamic.Dynamic"/utf8>>; {type, _, _, Type_} -> case Type_ of boolean -> <<"Bool"/utf8>>; string -> <<"String"/utf8>>; number -> <<"Int"/utf8>>; integer -> <<"Int"/utf8>>; array_type -> <<"List(dynamic.Dynamic)"/utf8>>; object_type -> <<"Dict(String, dynamic.Dynamic)"/utf8>>; null -> <<"Nil"/utf8>> end; {one_of, _, _, Schemas} -> Name; {any_of, _, _, Schemas} -> Name; {all_of, _, _, Schemas} -> Name; {'not', _, _, Schema@1} -> type_name(Schema@1, <>) end, case Nullable@1 of true -> <<<<"option.Option("/utf8, Name@1/binary>>/binary, ")"/utf8>>; false -> Name@1 end. -file("src/mcp_toolkit/core/json_schema.gleam", 828). -spec ensure_no_duplicate_properties(object_schema(), binary(), binary()) -> {ok, nil} | {error, codegen_error()}. ensure_no_duplicate_properties(Schema, Type_name, Constructor_name) -> Names = erlang:element(2, Schema), Recorded = gleam@set:new(), _pipe = gleam@list:try_fold( Names, Recorded, fun(Recorded@1, Pair) -> Field_name = justin:snake_case(erlang:element(1, Pair)), Before = gleam@set:size(Recorded@1), Recorded@2 = gleam@set:insert(Recorded@1, Field_name), case Before =:= gleam@set:size(Recorded@2) of false -> {ok, Recorded@2}; true -> {error, {duplicate_property_error, Type_name, Constructor_name, Field_name}} end end ), gleam@result:replace(_pipe, nil). -file("src/mcp_toolkit/core/json_schema.gleam", 901). -spec ensure_constructor_unique(generator(), binary()) -> {ok, generator()} | {error, codegen_error()}. ensure_constructor_unique(Gen, Name) -> Before = gleam@set:size(erlang:element(11, Gen)), Constructors = gleam@set:insert(erlang:element(11, Gen), Name), case Before =:= gleam@set:size(Constructors) of false -> {ok, {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), Constructors}}; true -> {error, {duplicate_constructor_error, Name}} end. -file("src/mcp_toolkit/core/json_schema.gleam", 928). -spec gen_register_nullable(generator(), boolean()) -> generator(). gen_register_nullable(Gen, Nullable) -> case Nullable of false -> Gen; true -> {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), true, erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)} end. -file("src/mcp_toolkit/core/json_schema.gleam", 973). -spec gen_add_function(generator(), binary(), binary()) -> {ok, generator()} | {error, codegen_error()}. gen_add_function(Gen, Name, Body) -> Before = maps:size(erlang:element(9, Gen)), Functions = gleam@dict:insert(erlang:element(9, Gen), Name, Body), case maps:size(Functions) =:= Before of false -> {ok, {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), Functions, erlang:element(10, Gen), erlang:element(11, Gen)}}; true -> {error, {duplicate_function_error, Name}} end. -file("src/mcp_toolkit/core/json_schema.gleam", 986). -spec gen_add_type(generator(), binary(), binary()) -> {ok, generator()} | {error, codegen_error()}. gen_add_type(Gen, Name, Body) -> Before = maps:size(erlang:element(8, Gen)), Types = gleam@dict:insert(erlang:element(8, Gen), Name, Body), case maps:size(Types) =:= Before of false -> {ok, {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), Types, erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)}}; true -> {error, {duplicate_type_error, Name}} end. -file("src/mcp_toolkit/core/json_schema.gleam", 913). -spec gen_enum_type_string(generator(), binary(), list(binary())) -> {ok, generator()} | {error, codegen_error()}. gen_enum_type_string(Gen, Name, Variants) -> gleam@bool:guard( Variants =:= [], {error, empty_enum_error}, fun() -> Variants@1 = begin _pipe = Variants, _pipe@1 = gleam@list:map( _pipe, fun(V) -> <<<<" "/utf8, (justin:pascal_case(V))/binary>>/binary, "\n"/utf8>> end ), gleam@string:join(_pipe@1, <<""/utf8>>) end, Src = <<<<<<<<"pub type "/utf8, Name/binary>>/binary, " {\n"/utf8>>/binary, Variants@1/binary>>/binary, "}"/utf8>>, gen_add_type(Gen, Name, Src) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 999). -spec gen_to_string(generator()) -> binary(). gen_to_string(Gen) -> Imp = fun(Used, Module) -> case Used of true -> [Module]; false -> [] end end, Imports = begin _pipe = [Imp(erlang:element(2, Gen), <<"decode"/utf8>>), Imp(erlang:element(6, Gen), <<"gleam/dict"/utf8>>), Imp(erlang:element(4, Gen), <<"gleam/dynamic"/utf8>>), Imp(erlang:element(3, Gen), <<"gleam/json"/utf8>>), Imp(erlang:element(5, Gen), <<"gleam/option"/utf8>>)], _pipe@1 = lists:append(_pipe), _pipe@2 = gleam@list:map( _pipe@1, fun(M) -> <<"import "/utf8, M/binary>> end ), gleam@string:join(_pipe@2, <<"\n"/utf8>>) end, Defs = fun(Items) -> _pipe@3 = Items, _pipe@4 = maps:to_list(_pipe@3), _pipe@5 = gleam@list:sort( _pipe@4, fun(A, B) -> gleam@string:compare(erlang:element(1, A), erlang:element(1, B)) end ), _pipe@6 = gleam@list:map( _pipe@5, fun(A@1) -> erlang:element(2, A@1) end ), gleam@string:join(_pipe@6, <<"\n\n"/utf8>>) end, Block = fun(S) -> case S of <<""/utf8>> -> []; _ -> [S] end end, Helper__optional_property = case erlang:element(3, Gen) andalso erlang:element( 7, Gen ) of false -> []; true -> [<<"fn helper__optional_property(\n object: List(#(String, json.Json)),\n key: String,\n value: option.Option(a),\n to_json: fn(a) -> json.Json,\n) -> List(#(String, json.Json)) {\n case value {\n option.Some(value) -> [#(key, to_json(value)), ..object]\n option.None -> object\n }\n}"/utf8>>] end, Helper__dict_to_json = case erlang:element(3, Gen) andalso erlang:element( 6, Gen ) of false -> []; true -> [<<"fn helper__dict_to_json(\n data: dict.Dict(String, t),\n to_json: fn(t) -> json.Json,\n) -> json.Json {\n data\n |> dict.to_list\n |> list.map(fn(pair) { #(pair.0, to_json(pair.1)) })\n |> json.object\n}"/utf8>>] end, _pipe@7 = [Block(Imports), Block(Defs(erlang:element(8, Gen))), Block(Defs(erlang:element(9, Gen))), Helper__dict_to_json, Helper__optional_property], _pipe@8 = lists:append(_pipe@7), gleam@string:join(_pipe@8, <<"\n\n"/utf8>>). -file("src/mcp_toolkit/core/json_schema.gleam", 1085). -spec en_ref(binary(), gleam@option:option(binary()), boolean()) -> {ok, out()} | {error, codegen_error()}. en_ref(Ref, Data, Nullable) -> Name = case gleam@string:split(Ref, <<"/"/utf8>>) of [<<"#"/utf8>>, <<"definitions"/utf8>>, Def_name] -> Def_name; [<<"#"/utf8>>, <<"$defs"/utf8>>, Def_name@1] -> Def_name@1; _ -> <<"unknown"/utf8>> end, Src = <<(justin:snake_case(Name))/binary, "_to_json"/utf8>>, Src@1 = case {Data, Nullable} of {none, false} -> Src; {none, true} -> <<<<"json.nullable(_, "/utf8, Src/binary>>/binary, ")"/utf8>>; {{some, Data@1}, false} -> <<<<<>/binary, Data@1/binary>>/binary, ")"/utf8>>; {{some, Data@2}, true} -> <<<<<<<<"json.nullable("/utf8, Data@2/binary>>/binary, ", "/utf8>>/binary, Src/binary>>/binary, ")"/utf8>> end, Type_name = justin:pascal_case(Name), Type_name@1 = case Nullable of false -> Type_name; true -> <<<<"option.Option("/utf8, Type_name/binary>>/binary, ")"/utf8>> end, {ok, {out, Src@1, Type_name@1}}. -file("src/mcp_toolkit/core/json_schema.gleam", 1113). -spec de_ref(binary(), boolean()) -> {ok, out()} | {error, codegen_error()}. de_ref(Ref, Nullable) -> Name = case gleam@string:split(Ref, <<"/"/utf8>>) of [<<"#"/utf8>>, <<"definitions"/utf8>>, Def_name] -> Def_name; [<<"#"/utf8>>, <<"$defs"/utf8>>, Def_name@1] -> Def_name@1; _ -> <<"unknown"/utf8>> end, Src = <<(justin:snake_case(Name))/binary, "_decoder()"/utf8>>, Src@1 = case Nullable of false -> Src; true -> <<<<"decode.optional("/utf8, Src/binary>>/binary, ")"/utf8>> end, Type_name = justin:pascal_case(Name), Type_name@1 = case Nullable of false -> Type_name; true -> <<<<"option.Option("/utf8, Type_name/binary>>/binary, ")"/utf8>> end, {ok, {out, Src@1, Type_name@1}}. -file("src/mcp_toolkit/core/json_schema.gleam", 1141). -spec pro_data_name(gleam@option:option(binary())) -> property_data_name(). pro_data_name(Name) -> case Name of none -> property_data_none; {some, N} -> {property_data_access, N} end. -file("src/mcp_toolkit/core/json_schema.gleam", 1347). -spec en_enum_string( list(binary()), boolean(), gleam@option:option(binary()), binary() ) -> {ok, out()} | {error, codegen_error()}. en_enum_string(Variants, Nullable, Data, Position_name) -> Type_name = Position_name, Src = <<<<"json.string(case "/utf8, (gleam@option:unwrap(Data, <<"data"/utf8>>))/binary>>/binary, " {\n"/utf8>>, Variants@1 = begin _pipe = Variants, _pipe@1 = gleam@list:map( _pipe, fun(V) -> <<<<<<<<" "/utf8, (justin:pascal_case(V))/binary>>/binary, " -> \""/utf8>>/binary, V/binary>>/binary, "\"\n"/utf8>> end ), erlang:list_to_binary(_pipe@1) end, Src@1 = <<<>/binary, " })"/utf8>>, Src@2 = case Nullable orelse (Data =:= none) of true -> <<<<"fn(data) { "/utf8, Src@1/binary>>/binary, " }"/utf8>>; false -> Src@1 end, Out = case Nullable of true -> Type_name@1 = <<<<"option.Option("/utf8, Type_name/binary>>/binary, ")"/utf8>>, Src@3 = case Data of {some, Data@1} -> <<<<<<<<"json.nullable("/utf8, Data@1/binary>>/binary, ", "/utf8>>/binary, Src@2/binary>>/binary, ")"/utf8>>; none -> <<<<"json.nullable(_, "/utf8, Src@2/binary>>/binary, ")"/utf8>> end, {out, Src@3, Type_name@1}; false -> {out, Src@2, Type_name} end, {ok, Out}. -file("src/mcp_toolkit/core/json_schema.gleam", 1438). -spec en_nullable(binary(), binary(), boolean(), gleam@option:option(binary())) -> out(). en_nullable(Src, Type_name, Nullable, Data) -> case Nullable of true -> Type_name@1 = <<<<"option.Option("/utf8, Type_name/binary>>/binary, ")"/utf8>>, Src@1 = case Data of {some, Data@1} -> <<<<<<<<"json.nullable("/utf8, Data@1/binary>>/binary, ", "/utf8>>/binary, Src/binary>>/binary, ")"/utf8>>; none -> <<<<"json.nullable(_, "/utf8, Src/binary>>/binary, ")"/utf8>> end, {out, Src@1, Type_name@1}; false -> Src@2 = case Data of {some, Data@2} -> <<<<<>/binary, Data@2/binary>>/binary, ")"/utf8>>; none -> Src end, {out, Src@2, Type_name} end. -file("src/mcp_toolkit/core/json_schema.gleam", 1426). -spec en_type(type(), boolean(), gleam@option:option(binary())) -> out(). en_type(T, Nullable, Data) -> {Src, Type_name} = case T of boolean -> {<<"json.bool"/utf8>>, <<"Bool"/utf8>>}; string -> {<<"json.string"/utf8>>, <<"String"/utf8>>}; number -> {<<"json.int"/utf8>>, <<"Int"/utf8>>}; integer -> {<<"json.int"/utf8>>, <<"Int"/utf8>>}; array_type -> {<<"json.array(_, json.string)"/utf8>>, <<"List(String)"/utf8>>}; object_type -> {<<"json.object"/utf8>>, <<"dict.Dict(String, json.Json)"/utf8>>}; null -> {<<"fn(_) { json.null() }"/utf8>>, <<"Nil"/utf8>>} end, en_nullable(Src, Type_name, Nullable, Data). -file("src/mcp_toolkit/core/json_schema.gleam", 1463). -spec de_nullable(binary(), binary(), boolean()) -> out(). de_nullable(Src, Type_name, Nullable) -> case Nullable of true -> Type_name@1 = <<<<"option.Option("/utf8, Type_name/binary>>/binary, ")"/utf8>>, Src@1 = <<<<"decode.optional("/utf8, Src/binary>>/binary, ")"/utf8>>, {out, Src@1, Type_name@1}; false -> {out, Src, Type_name} end. -file("src/mcp_toolkit/core/json_schema.gleam", 1394). -spec de_enum(list(binary()), boolean(), binary()) -> {ok, out()} | {error, codegen_error()}. de_enum(Variants, Nullable, Position_name) -> Type_name = Position_name, Src = <<"decode.then(decode.string, fn(s) {\n case s {\n"/utf8>>, Variants@1 = gleam@list:map( Variants, fun(V) -> <<<<<<<<" \""/utf8, V/binary>>/binary, "\" -> decode.into("/utf8>>/binary, (justin:pascal_case(V))/binary>>/binary, ")\n"/utf8>> end ), Src@1 = <>, Src@2 = <<<<< decode.fail(\""/utf8>>/binary, Type_name/binary>>/binary, "\")\n"/utf8>>, Src@3 = <>, {ok, de_nullable(Src@3, Type_name, Nullable)}. -file("src/mcp_toolkit/core/json_schema.gleam", 1411). -spec de_type(type(), boolean()) -> out(). de_type(T, Nullable) -> {Src, Type_name} = case T of boolean -> {<<"decode.bool"/utf8>>, <<"Bool"/utf8>>}; string -> {<<"decode.string"/utf8>>, <<"String"/utf8>>}; number -> {<<"decode.int"/utf8>>, <<"Int"/utf8>>}; integer -> {<<"decode.int"/utf8>>, <<"Int"/utf8>>}; array_type -> {<<"decode.list(decode.dynamic)"/utf8>>, <<"List(dynamic.Dynamic)"/utf8>>}; object_type -> {<<"decode.dict(decode.string, decode.dynamic)"/utf8>>, <<"dict.Dict(String, dynamic.Dynamic)"/utf8>>}; null -> {<<"decode.constant(Nil, null)"/utf8>>, <<"Nil"/utf8>>} end, de_nullable(Src, Type_name, Nullable). -file("src/mcp_toolkit/core/json_schema.gleam", 1181). -spec en_composite_schema( list(schema()), boolean(), gleam@option:option(binary()), binary() ) -> {ok, out()} | {error, codegen_error()}. en_composite_schema(Schemas, Nullable, Data, Name) -> gleam@result:'try'(case Schemas of [First | _] -> {ok, First}; [] -> {error, empty_enum_error} end, fun(First_schema) -> en_schema(First_schema, Data, Name) end). -file("src/mcp_toolkit/core/json_schema.gleam", 1061). -spec en_schema(schema(), gleam@option:option(binary()), binary()) -> {ok, out()} | {error, codegen_error()}. en_schema(Schema, Data, Name) -> case Schema of {one_of, Nullable, _, Schemas} -> en_composite_schema(Schemas, Nullable, Data, Name); {any_of, Nullable, _, Schemas} -> en_composite_schema(Schemas, Nullable, Data, Name); {all_of, Nullable, _, Schemas} -> en_composite_schema(Schemas, Nullable, Data, Name); {array, Nullable@1, _, Items} -> en_array(Items, Nullable@1, Data, <>); {empty, _} -> {error, cannot_convert_empty_to_json_error}; {enum, Nullable@2, _, Variants} -> en_enum_string(Variants, Nullable@2, Data, Name); {object, Nullable@3, _, Schema@1} -> en_object_schema(Schema@1, Nullable@3, pro_data_name(Data), Name); {ref, Nullable@4, _, Ref} -> en_ref(Ref, Data, Nullable@4); {type, Nullable@5, _, Type_} -> {ok, en_type(Type_, Nullable@5, Data)}; {'not', Nullable@6, _, Schema@2} -> en_schema(Schema@2, Data, <>) end. -file("src/mcp_toolkit/core/json_schema.gleam", 935). -spec gen_add_encoder(generator(), binary(), schema()) -> {ok, generator()} | {error, codegen_error()}. gen_add_encoder(Gen, Name, Schema) -> gleam@result:'try'( en_schema(Schema, {some, <<"data"/utf8>>}, Name), fun(Out) -> Name@1 = <<(justin:snake_case(Name))/binary, "_to_json"/utf8>>, Src = <<<<<<<<<<<<"pub fn "/utf8, Name@1/binary>>/binary, "(data: "/utf8>>/binary, (erlang:element(3, Out))/binary>>/binary, ") -> json.Json {\n "/utf8>>/binary, (erlang:element(2, Out))/binary>>/binary, "\n}"/utf8>>, gen_add_function(Gen, Name@1, Src) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 705). -spec gen_encoders(generator(), binary(), root_schema()) -> {ok, generator()} | {error, codegen_error()}. gen_encoders(Gen, Root, Schema) -> gen_add_encoder(Gen, Root, erlang:element(3, Schema)). -file("src/mcp_toolkit/core/json_schema.gleam", 1254). -spec en_object_schema( object_schema(), boolean(), property_data_name(), binary() ) -> {ok, out()} | {error, codegen_error()}. en_object_schema(Schema, Nullable, Data, Name) -> {object_schema, Properties, Required, _, _} = Schema, Property_data = fun(Field_name) -> Field_name@1 = justin:snake_case(Field_name), case Data of property_data_direct -> Field_name@1; {property_data_access, Name@1} when not Nullable -> <<<>/binary, Field_name@1/binary>>; _ -> <<"data."/utf8, Field_name@1/binary>> end end, gleam@result:'try'( gleam@list:try_map( Properties, fun(P) -> Name@2 = <>, Data@1 = Property_data(erlang:element(1, P)), gleam@result:map( en_schema(erlang:element(2, P), {some, Data@1}, Name@2), fun(Out) -> {erlang:element(1, P), erlang:element(2, Out)} end ) end ), fun(Properties@1) -> Properties@2 = begin _pipe = Properties@1, gleam@list:map( _pipe, fun(P@1) -> <<<<<<<<"\n #(\""/utf8, (erlang:element(1, P@1))/binary>>/binary, "\", "/utf8>>/binary, (erlang:element(2, P@1))/binary>>/binary, "),"/utf8>> end ) end, Src = case Properties@2 of [] -> <<"[]"/utf8>>; P@2 -> <<<<"["/utf8, (erlang:list_to_binary(P@2))/binary>>/binary, "\n ]"/utf8>> end, Src@1 = <<<<"json.object("/utf8, Src/binary>>/binary, ")"/utf8>>, Src@2 = case Nullable of true -> Data@2 = case Data of {property_data_access, Name@3} -> Name@3; property_data_direct -> <<"data"/utf8>>; property_data_none -> <<"data"/utf8>> end, <<<<<<<<"case "/utf8, Data@2/binary>>/binary, " {\n option.Some(data) -> "/utf8>>/binary, Src@1/binary>>/binary, "\n option.None -> json.null()\n }"/utf8>>; false -> Src@1 end, Src@3 = case Data of property_data_none -> <<<<"fn(data) { "/utf8, Src@2/binary>>/binary, " }"/utf8>>; _ -> Src@2 end, Type_name = case Nullable of true -> <<<<"option.Option("/utf8, Name/binary>>/binary, ")"/utf8>>; false -> Name end, {ok, {out, Src@3, Type_name}} end ). -file("src/mcp_toolkit/core/json_schema.gleam", 1324). -spec en_array(schema(), boolean(), gleam@option:option(binary()), binary()) -> {ok, out()} | {error, codegen_error()}. en_array(Schema, Nullable, Data, Position_name) -> gleam@result:'try'( en_schema(Schema, none, Position_name), fun(_use0) -> {out, Src, Type_name} = _use0, Type_name@1 = <<<<"List("/utf8, Type_name/binary>>/binary, ")"/utf8>>, Data@1 = gleam@option:unwrap(Data, <<"_"/utf8>>), case Nullable of false -> Src@1 = <<<<<<<<"json.array("/utf8, Data@1/binary>>/binary, ", "/utf8>>/binary, Src/binary>>/binary, ")"/utf8>>, {ok, {out, Src@1, Type_name@1}}; true -> Type_name@2 = <<<<"option.Option("/utf8, Type_name@1/binary>>/binary, ")"/utf8>>, Src@2 = <<<<"json.array(_, "/utf8, Src/binary>>/binary, ")"/utf8>>, Src@3 = <<<<<<<<"json.nullable("/utf8, Data@1/binary>>/binary, ", "/utf8>>/binary, Src@2/binary>>/binary, ")"/utf8>>, {ok, {out, Src@3, Type_name@2}} end end ). -file("src/mcp_toolkit/core/json_schema.gleam", 1166). -spec de_composite_schema(list(schema()), boolean(), binary()) -> {ok, out()} | {error, codegen_error()}. de_composite_schema(Schemas, Nullable, Name) -> gleam@result:'try'(case Schemas of [First | _] -> {ok, First}; [] -> {error, empty_enum_error} end, fun(First_schema) -> de_schema(First_schema, Name) end). -file("src/mcp_toolkit/core/json_schema.gleam", 1148). -spec de_schema(schema(), binary()) -> {ok, out()} | {error, codegen_error()}. de_schema(Schema, Name) -> case Schema of {one_of, Nullable, _, Schemas} -> de_composite_schema(Schemas, Nullable, Name); {any_of, Nullable, _, Schemas} -> de_composite_schema(Schemas, Nullable, Name); {all_of, Nullable, _, Schemas} -> de_composite_schema(Schemas, Nullable, Name); {array, Nullable@1, _, Items} -> de_array(Items, Nullable@1, <>); {empty, _} -> {ok, {out, <<"decode.dynamic"/utf8>>, <<"dynamic.Dynamic"/utf8>>}}; {enum, Nullable@2, _, Variants} -> de_enum(Variants, Nullable@2, Name); {object, Nullable@3, _, Schema@1} -> de_object_schema(Schema@1, Nullable@3, Name); {ref, Nullable@4, _, Ref} -> de_ref(Ref, Nullable@4); {type, Nullable@5, _, Type_} -> {ok, de_type(Type_, Nullable@5)}; {'not', Nullable@6, _, Schema@2} -> de_schema(Schema@2, <>) end. -file("src/mcp_toolkit/core/json_schema.gleam", 954). -spec gen_add_decoder(generator(), binary(), schema()) -> {ok, generator()} | {error, codegen_error()}. gen_add_decoder(Gen, Name, Schema) -> gleam@result:'try'( de_schema(Schema, Name), fun(Out) -> Fn_name = <<(justin:snake_case(Name))/binary, "_decoder"/utf8>>, Src = <<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "() -> decode.Decoder("/utf8>>/binary, (erlang:element(3, Out))/binary>>/binary, ") {\n "/utf8>>/binary, (erlang:element(2, Out))/binary>>/binary, "\n}"/utf8>>, gen_add_function(Gen, Name, Src) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 713). -spec gen_decoders(generator(), binary(), root_schema()) -> {ok, generator()} | {error, codegen_error()}. gen_decoders(Gen, Root, Schema) -> gen_add_decoder(Gen, Root, erlang:element(3, Schema)). -file("src/mcp_toolkit/core/json_schema.gleam", 1197). -spec de_object_schema(object_schema(), boolean(), binary()) -> {ok, out()} | {error, codegen_error()}. de_object_schema(Schema, Nullable, Name) -> {object_schema, Properties, Required, _, _} = Schema, gleam@result:'try'( gleam@list:try_map( Properties, fun(Prop) -> gleam@result:map( de_schema( erlang:element(2, Prop), <> ), fun(S) -> Is_required = gleam@list:contains( Required, erlang:element(1, Prop) ), {erlang:element(1, Prop), S, not Is_required} end ) end ), fun(Properties@1) -> Params = begin _pipe = Properties@1, _pipe@1 = gleam@list:map( _pipe, fun(N) -> Name@1 = justin:snake_case(erlang:element(1, N)), <<<<" use "/utf8, Name@1/binary>>/binary, " <- decode.parameter"/utf8>> end ), gleam@string:join(_pipe@1, <<"\n"/utf8>>) end, Fields = begin _pipe@2 = Properties@1, _pipe@3 = gleam@list:map( _pipe@2, fun(P) -> Field = case erlang:element(3, P) of true -> <<" |> decode.optional_field(\""/utf8>>; false -> <<" |> decode.field(\""/utf8>> end, <<<<<<<>/binary, "\", "/utf8>>/binary, (erlang:element(2, (erlang:element(2, P))))/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@3, <<"\n"/utf8>>) end, Keys = begin _pipe@4 = Properties@1, _pipe@5 = gleam@list:map( _pipe@4, fun(N@1) -> <<(justin:snake_case(erlang:element(1, N@1)))/binary, ":"/utf8>> end ), gleam@string:join(_pipe@5, <<", "/utf8>>) end, Src = <<<<<<<<<<<<<<"decode.into({\n"/utf8, Params/binary>>/binary, "\n "/utf8>>/binary, Name/binary>>/binary, "("/utf8>>/binary, Keys/binary>>/binary, ")\n })\n"/utf8>>/binary, Fields/binary>>, {ok, de_nullable(Src, Name, Nullable)} end ). -file("src/mcp_toolkit/core/json_schema.gleam", 1383). -spec de_array(schema(), boolean(), binary()) -> {ok, out()} | {error, codegen_error()}. de_array(Schema, Nullable, Position_name) -> gleam@result:'try'( de_schema(Schema, Position_name), fun(_use0) -> {out, Src, Type_name} = _use0, Type_name@1 = <<<<"List("/utf8, Type_name/binary>>/binary, ")"/utf8>>, Src@1 = <<<<"decode.list("/utf8, Src/binary>>/binary, ")"/utf8>>, {ok, de_nullable(Src@1, Type_name@1, Nullable)} end ). -file("src/mcp_toolkit/core/json_schema.gleam", 849). -spec type_variant(generator(), binary(), object_schema()) -> {ok, {generator(), binary()}} | {error, codegen_error()}. type_variant(Gen, Name, Schema) -> Gen@1 = case erlang:element(3, Schema) of [] -> Gen; _ -> {generator, erlang:element(2, Gen), erlang:element(3, Gen), erlang:element(4, Gen), erlang:element(5, Gen), erlang:element(6, Gen), true, erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)} end, {object_schema, Properties, Required, _, _} = Schema, gleam@result:'try'( gleam@list:try_fold( Properties, Gen@1, fun(Gen@2, Prop) -> gen_type( Gen@2, <>, erlang:element(2, Prop) ) end ), fun(Gen@3) -> Property_is_required = fun(Prop_name) -> gleam@list:contains(Required, Prop_name) end, Properties@1 = begin _pipe = Properties, _pipe@1 = gleam@list:map( _pipe, fun(P) -> Is_required = Property_is_required(erlang:element(1, P)), {erlang:element(1, P), erlang:element(2, P), not Is_required} end ), _pipe@2 = gleam@list:sort( _pipe@1, fun(A, B) -> gleam@string:compare( erlang:element(1, A), erlang:element(1, B) ) end ), _pipe@3 = gleam@list:map( _pipe@2, fun(P@1) -> N = justin:snake_case(erlang:element(1, P@1)), Type_n = type_name( erlang:element(2, P@1), <> ), Type_n@1 = case erlang:element(3, P@1) of true -> <<<<"option.Option("/utf8, Type_n/binary>>/binary, ")"/utf8>>; false -> Type_n end, <<<<<<" "/utf8, N/binary>>/binary, ": "/utf8>>/binary, Type_n@1/binary>> end ), gleam@string:join(_pipe@3, <<",\n"/utf8>>) end, gleam@result:'try'( ensure_constructor_unique(Gen@3, Name), fun(Gen@4) -> Src = <<<<<<<<" "/utf8, Name/binary>>/binary, "(\n"/utf8>>/binary, Properties@1/binary>>/binary, ",\n )"/utf8>>, {ok, {Gen@4, Src}} end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 721). -spec gen_type(generator(), binary(), schema()) -> {ok, generator()} | {error, codegen_error()}. gen_type(Gen, Name, Schema) -> Name@1 = justin:pascal_case(Name), case Schema of {empty, _} -> {ok, {generator, erlang:element(2, Gen), erlang:element(3, Gen), true, erlang:element(5, Gen), erlang:element(6, Gen), erlang:element(7, Gen), erlang:element(8, Gen), erlang:element(9, Gen), erlang:element(10, Gen), erlang:element(11, Gen)}}; {ref, Nullable, _, _} -> {ok, gen_register_nullable(Gen, Nullable)}; {type, Nullable@1, _, _} -> {ok, gen_register_nullable(Gen, Nullable@1)}; {enum, Nullable@2, _, Variants} -> Gen@1 = gen_register_nullable(Gen, Nullable@2), gen_enum_type_string(Gen@1, Name@1, Variants); {object, Nullable@3, _, Schema@1} -> Gen@2 = gen_register_nullable(Gen, Nullable@3), gen_register_object(Gen@2, Name@1, Schema@1); {array, Nullable@4, _, Items} -> Gen@3 = gen_register_nullable(Gen, Nullable@4), gen_type(Gen@3, <>, Items); {one_of, Nullable@5, _, Schemas} -> Gen@4 = gen_register_nullable(Gen, Nullable@5), gleam@list:try_fold( Schemas, Gen@4, fun(Gen@5, Schema@2) -> gen_type(Gen@5, <>, Schema@2) end ); {any_of, Nullable@5, _, Schemas} -> Gen@4 = gen_register_nullable(Gen, Nullable@5), gleam@list:try_fold( Schemas, Gen@4, fun(Gen@5, Schema@2) -> gen_type(Gen@5, <>, Schema@2) end ); {all_of, Nullable@5, _, Schemas} -> Gen@4 = gen_register_nullable(Gen, Nullable@5), gleam@list:try_fold( Schemas, Gen@4, fun(Gen@5, Schema@2) -> gen_type(Gen@5, <>, Schema@2) end ); {'not', Nullable@6, _, Schema@3} -> Gen@6 = gen_register_nullable(Gen, Nullable@6), gen_type(Gen@6, <>, Schema@3) end. -file("src/mcp_toolkit/core/json_schema.gleam", 814). -spec gen_register_object(generator(), binary(), object_schema()) -> {ok, generator()} | {error, codegen_error()}. gen_register_object(Gen, Name, Schema) -> gleam@result:'try'( ensure_no_duplicate_properties(Schema, Name, Name), fun(_) -> gleam@result:'try'( type_variant(Gen, Name, Schema), fun(_use0) -> {Gen@1, Src} = _use0, Src@1 = <<<<<<<<"pub type "/utf8, Name/binary>>/binary, " {\n"/utf8>>/binary, Src/binary>>/binary, "\n}"/utf8>>, Type_name = Name, gen_add_type(Gen@1, Type_name, Src@1) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 682). -spec gen_types(generator(), binary(), root_schema()) -> {ok, generator()} | {error, codegen_error()}. gen_types(Gen, _, Schema) -> gleam@list:try_fold( erlang:element(2, Schema), Gen, fun(Gen@1, Def) -> gen_type(Gen@1, erlang:element(1, Def), erlang:element(2, Def)) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 661). -spec generate(generator(), root_schema()) -> {ok, binary()} | {error, codegen_error()}. generate(Gen, Schema) -> Root = justin:pascal_case(erlang:element(10, Gen)), gleam@result:'try'( gen_types(Gen, Root, Schema), fun(Gen@1) -> gleam@result:'try'(case erlang:element(2, Gen@1) of true -> gen_decoders(Gen@1, Root, Schema); false -> {ok, Gen@1} end, fun(Gen@2) -> gleam@result:map(case erlang:element(3, Gen@2) of true -> gen_encoders(Gen@2, Root, Schema); false -> {ok, Gen@2} end, fun(Gen@3) -> gen_to_string(Gen@3) end) end) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 306). -spec decode_object( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_object(_, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> Properties = case gleam_stdlib:map_get( Data, <<"properties"/utf8>> ) of {ok, D} -> decode_schema_dict(D); {error, _} -> {ok, []} end, Pattern_properties = case gleam_stdlib:map_get( Data, <<"patternProperties"/utf8>> ) of {ok, D@1} -> decode_schema_dict(D@1); {error, _} -> {ok, []} end, Required = case gleam_stdlib:map_get( Data, <<"required"/utf8>> ) of {ok, D@2} -> gleam@dynamic@decode:run( D@2, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ); {error, _} -> {ok, []} end, Additional_properties = case gleam_stdlib:map_get( Data, <<"additionalProperties"/utf8>> ) of {ok, D@3} -> case gleam@dynamic@decode:run( D@3, {decoder, fun gleam@dynamic@decode:decode_bool/1} ) of {ok, true} -> {ok, {some, {empty, []}}}; {ok, false} -> {ok, none}; {error, _} -> _pipe = decode_schema(D@3), gleam@result:map( _pipe, fun(Field@0) -> {some, Field@0} end ) end; {error, _} -> {ok, {some, {empty, []}}} end, gleam@result:'try'( Properties, fun(Properties@1) -> gleam@result:'try'( Pattern_properties, fun(Pattern_properties@1) -> gleam@result:'try'( Required, fun(Required@1) -> gleam@result:'try'( Additional_properties, fun(Additional_properties@1) -> {ok, {object, Nullable, Metadata, {object_schema, Properties@1, Required@1, Additional_properties@1, Pattern_properties@1}}} end ) end ) end ) end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 272). -spec decode_schema(gleam@dynamic:dynamic_()) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_schema(Data) -> gleam@result:'try'( gleam@dynamic@decode:run( Data, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Data@1) -> Decoder = begin _pipe = key_decoder(Data@1, <<"enum"/utf8>>, fun decode_enum/2), _pipe@1 = gleam@result:lazy_or( _pipe, fun() -> key_decoder(Data@1, <<"$ref"/utf8>>, fun decode_ref/2) end ), _pipe@2 = gleam@result:lazy_or( _pipe@1, fun() -> key_decoder( Data@1, <<"items"/utf8>>, fun decode_array/2 ) end ), _pipe@3 = gleam@result:lazy_or( _pipe@2, fun() -> key_decoder( Data@1, <<"properties"/utf8>>, fun decode_object/2 ) end ), _pipe@4 = gleam@result:lazy_or( _pipe@3, fun() -> key_decoder( Data@1, <<"oneOf"/utf8>>, fun decode_one_of/2 ) end ), _pipe@5 = gleam@result:lazy_or( _pipe@4, fun() -> key_decoder( Data@1, <<"anyOf"/utf8>>, fun decode_any_of/2 ) end ), _pipe@6 = gleam@result:lazy_or( _pipe@5, fun() -> key_decoder( Data@1, <<"allOf"/utf8>>, fun decode_all_of/2 ) end ), _pipe@7 = gleam@result:lazy_or( _pipe@6, fun() -> key_decoder(Data@1, <<"not"/utf8>>, fun decode_not/2) end ), _pipe@8 = gleam@result:lazy_or( _pipe@7, fun() -> key_decoder(Data@1, <<"type"/utf8>>, fun decode_type/2) end ), gleam@result:unwrap(_pipe@8, fun() -> decode_empty(Data@1) end) end, Decoder() end ). -file("src/mcp_toolkit/core/json_schema.gleam", 239). -spec decode_definitions(gleam@dynamic:dynamic_()) -> {ok, list({binary(), schema()})} | {error, list(gleam@dynamic@decode:decode_error())}. decode_definitions(Data) -> gleam@result:'try'( gleam@dynamic@decode:run( Data, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Obj) -> To_schema_list = fun(Map_dyn) -> gleam@result:'try'( gleam@dynamic@decode:run( Map_dyn, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Entries) -> _pipe = Entries, _pipe@1 = maps:to_list(_pipe), gleam@list:try_map( _pipe@1, fun(Entry) -> {K, V} = Entry, _pipe@2 = decode_schema(V), gleam@result:map(_pipe@2, fun(S) -> {K, S} end) end ) end ) end, case gleam_stdlib:map_get(Obj, <<"$defs"/utf8>>) of {ok, Defs} -> To_schema_list(Defs); {error, _} -> case gleam_stdlib:map_get(Obj, <<"definitions"/utf8>>) of {ok, Defs@1} -> To_schema_list(Defs@1); {error, _} -> {ok, []} end end end ). -file("src/mcp_toolkit/core/json_schema.gleam", 231). -spec decoder(gleam@dynamic:dynamic_()) -> {ok, root_schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decoder(Data) -> gleam@result:'try'( decode_definitions(Data), fun(Defs) -> gleam@result:'try'( decode_schema(Data), fun(Root) -> {ok, {root_schema, Defs, Root}} end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 395). -spec decode_schema_dict(gleam@dynamic:dynamic_()) -> {ok, list({binary(), schema()})} | {error, list(gleam@dynamic@decode:decode_error())}. decode_schema_dict(Data) -> gleam@result:'try'( gleam@dynamic@decode:run( Data, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Entries) -> _pipe = Entries, _pipe@1 = maps:to_list(_pipe), gleam@list:try_map( _pipe@1, fun(Entry) -> {K, V} = Entry, _pipe@2 = decode_schema(V), gleam@result:map(_pipe@2, fun(S) -> {K, S} end) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 353). -spec decode_object_schema(gleam@dynamic:dynamic_()) -> {ok, object_schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_object_schema(Data) -> gleam@result:'try'( gleam@dynamic@decode:run( Data, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Obj) -> Properties = case gleam_stdlib:map_get(Obj, <<"properties"/utf8>>) of {ok, D} -> decode_schema_dict(D); {error, _} -> {ok, []} end, Pattern_properties = case gleam_stdlib:map_get( Obj, <<"patternProperties"/utf8>> ) of {ok, D@1} -> decode_schema_dict(D@1); {error, _} -> {ok, []} end, Required = case gleam_stdlib:map_get(Obj, <<"required"/utf8>>) of {ok, D@2} -> gleam@dynamic@decode:run( D@2, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ) ); {error, _} -> {ok, []} end, Additional_properties = case gleam_stdlib:map_get( Obj, <<"additionalProperties"/utf8>> ) of {ok, D@3} -> case gleam@dynamic@decode:run( D@3, {decoder, fun gleam@dynamic@decode:decode_bool/1} ) of {ok, true} -> {ok, {some, {empty, []}}}; {ok, false} -> {ok, none}; {error, _} -> _pipe = decode_schema(D@3), gleam@result:map( _pipe, fun(Field@0) -> {some, Field@0} end ) end; {error, _} -> {ok, {some, {empty, []}}} end, gleam@result:'try'( Properties, fun(Properties@1) -> gleam@result:'try'( Pattern_properties, fun(Pattern_properties@1) -> gleam@result:'try'( Required, fun(Required@1) -> gleam@result:'try'( Additional_properties, fun(Additional_properties@1) -> {ok, {object_schema, Properties@1, Required@1, Additional_properties@1, Pattern_properties@1}} end ) end ) end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 410). -spec decode_array( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_array(Items, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> _pipe = decode_schema(Items), gleam@result:map( _pipe, fun(_capture) -> {array, Nullable, Metadata, _capture} end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 420). -spec decode_one_of( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_one_of(Schemas, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> gleam@result:'try'( gleam@dynamic@decode:run( Schemas, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Schema_dyns) -> gleam@result:'try'( gleam@list:try_map( Schema_dyns, fun decode_schema/1 ), fun(Schemas@1) -> {ok, {one_of, Nullable, Metadata, Schemas@1}} end ) end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 431). -spec decode_all_of( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_all_of(Schemas, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> gleam@result:'try'( gleam@dynamic@decode:run( Schemas, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Schema_dyns) -> gleam@result:'try'( gleam@list:try_map( Schema_dyns, fun decode_schema/1 ), fun(Schemas@1) -> {ok, {all_of, Nullable, Metadata, Schemas@1}} end ) end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 442). -spec decode_any_of( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_any_of(Schemas, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> gleam@result:'try'( gleam@dynamic@decode:run( Schemas, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_dynamic/1} ) ), fun(Schema_dyns) -> gleam@result:'try'( gleam@list:try_map( Schema_dyns, fun decode_schema/1 ), fun(Schemas@1) -> {ok, {any_of, Nullable, Metadata, Schemas@1}} end ) end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 453). -spec decode_not( gleam@dynamic:dynamic_(), gleam@dict:dict(binary(), gleam@dynamic:dynamic_()) ) -> {ok, schema()} | {error, list(gleam@dynamic@decode:decode_error())}. decode_not(Schema, Data) -> gleam@result:'try'( get_nullable(Data), fun(Nullable) -> gleam@result:'try'( get_metadata(Data), fun(Metadata) -> gleam@result:'try'( decode_schema(Schema), fun(Schema@1) -> {ok, {'not', Nullable, Metadata, Schema@1}} end ) end ) end ). -file("src/mcp_toolkit/core/json_schema.gleam", 112). -spec object_schema_to_json(object_schema()) -> list({binary(), gleam@json:json()}). object_schema_to_json(Schema) -> Props_json = fun(Props) -> gleam@json:object( gleam@list:map( Props, fun(Property) -> {erlang:element(1, Property), gleam@json:object( schema_to_json(erlang:element(2, Property)) )} end ) ) end, {object_schema, Properties, Required, Additional_properties, Pattern_properties} = Schema, Data = [], Data@1 = case Pattern_properties of [] -> Data; P -> [{<<"patternProperties"/utf8>>, Props_json(P)} | Data] end, Data@2 = case Additional_properties of none -> Data@1; {some, Schema@1} -> [{<<"additionalProperties"/utf8>>, gleam@json:object(schema_to_json(Schema@1))} | Data@1] end, Data@3 = case Required of [] -> Data@2; R -> [{<<"required"/utf8>>, gleam@json:array(R, fun gleam@json:string/1)} | Data@2] end, Data@4 = case Properties of [] -> Data@3; P@1 -> [{<<"properties"/utf8>>, Props_json(P@1)} | Data@3] end, Data@4. -file("src/mcp_toolkit/core/json_schema.gleam", 156). -spec schema_to_json(schema()) -> list({binary(), gleam@json:json()}). schema_to_json(Schema) -> case Schema of {empty, Metadata} -> _pipe = [], add_metadata(_pipe, Metadata); {ref, Nullable, Metadata@1, Ref} -> _pipe@1 = [{<<"$ref"/utf8>>, gleam@json:string(Ref)}], _pipe@2 = add_nullable(_pipe@1, Nullable), add_metadata(_pipe@2, Metadata@1); {type, Nullable@1, Metadata@2, Type_} -> _pipe@3 = [{<<"type"/utf8>>, type_to_json(Type_)}], _pipe@4 = add_nullable(_pipe@3, Nullable@1), add_metadata(_pipe@4, Metadata@2); {enum, Nullable@2, Metadata@3, Variants} -> _pipe@5 = [{<<"enum"/utf8>>, gleam@json:array(Variants, fun gleam@json:string/1)}], _pipe@6 = add_nullable(_pipe@5, Nullable@2), add_metadata(_pipe@6, Metadata@3); {array, Nullable@3, Metadata@4, Items} -> _pipe@7 = [{<<"items"/utf8>>, gleam@json:object(schema_to_json(Items))}], _pipe@8 = add_nullable(_pipe@7, Nullable@3), add_metadata(_pipe@8, Metadata@4); {object, Nullable@4, Metadata@5, Schema@1} -> _pipe@9 = object_schema_to_json(Schema@1), _pipe@10 = add_nullable(_pipe@9, Nullable@4), add_metadata(_pipe@10, Metadata@5); {one_of, Nullable@5, Metadata@6, Schemas} -> _pipe@11 = [{<<"oneOf"/utf8>>, gleam@json:array( Schemas, fun(S) -> gleam@json:object(schema_to_json(S)) end )}], _pipe@12 = add_nullable(_pipe@11, Nullable@5), add_metadata(_pipe@12, Metadata@6); {all_of, Nullable@6, Metadata@7, Schemas@1} -> _pipe@13 = [{<<"allOf"/utf8>>, gleam@json:array( Schemas@1, fun(S@1) -> gleam@json:object(schema_to_json(S@1)) end )}], _pipe@14 = add_nullable(_pipe@13, Nullable@6), add_metadata(_pipe@14, Metadata@7); {any_of, Nullable@7, Metadata@8, Schemas@2} -> _pipe@15 = [{<<"anyOf"/utf8>>, gleam@json:array( Schemas@2, fun(S@2) -> gleam@json:object(schema_to_json(S@2)) end )}], _pipe@16 = add_nullable(_pipe@15, Nullable@7), add_metadata(_pipe@16, Metadata@8); {'not', Nullable@8, Metadata@9, Schema@2} -> _pipe@17 = [{<<"not"/utf8>>, gleam@json:object(schema_to_json(Schema@2))}], _pipe@18 = add_nullable(_pipe@17, Nullable@8), add_metadata(_pipe@18, Metadata@9) end. -file("src/mcp_toolkit/core/json_schema.gleam", 96). -spec to_json(root_schema()) -> gleam@json:json(). to_json(Schema) -> Properties = schema_to_json(erlang:element(3, Schema)), Properties@1 = case erlang:element(2, Schema) of [] -> Properties; Definitions -> Definitions@1 = gleam@list:map( Definitions, fun(Definition) -> {erlang:element(1, Definition), gleam@json:object( schema_to_json(erlang:element(2, Definition)) )} end ), [{<<"$defs"/utf8>>, gleam@json:object(Definitions@1)} | Properties] end, gleam@json:object(Properties@1).