-module(castor). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/castor.gleam"). -export([ref/1, ref_decoder/1, boolean/0, integer/0, number/0, string/0, null/0, array/1, dict/1, object/1, enum_of_strings/1, field/2, optional_field/2, to_fields/1, encode_minimal/1, encode/1, decoder/0]). -export_type([ref/1, schema/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. -type ref(FSG) :: {ref, binary(), gleam@option:option(binary()), gleam@option:option(binary())} | {inline, FSG}. -type schema() :: {boolean, boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {integer, gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(integer()), boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {number, gleam@option:option(integer()), gleam@option:option(float()), gleam@option:option(float()), gleam@option:option(float()), gleam@option:option(float()), boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {string, gleam@option:option(integer()), gleam@option:option(integer()), gleam@option:option(binary()), gleam@option:option(binary()), boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {null, gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {array, gleam@option:option(integer()), gleam@option:option(integer()), boolean(), ref(schema()), boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {object, gleam@dict:dict(binary(), ref(schema())), list(binary()), gleam@option:option(ref(schema())), gleam@option:option(integer()), integer(), boolean(), gleam@option:option(binary()), gleam@option:option(binary()), boolean()} | {all_of, non_empty_list:non_empty_list(ref(schema()))} | {any_of, non_empty_list:non_empty_list(ref(schema()))} | {one_of, non_empty_list:non_empty_list(ref(schema()))} | {enum, non_empty_list:non_empty_list(oas@generator@utils:any_())} | always_passes | always_fails. -file("src/castor.gleam", 17). ?DOC(" Create a reference with no summary or description.\n"). -spec ref(binary()) -> ref(any()). ref(Thing) -> {ref, Thing, none, none}. -file("src/castor.gleam", 21). -spec ref_decoder(gleam@dynamic@decode:decoder(FSJ)) -> gleam@dynamic@decode:decoder(ref(FSJ)). ref_decoder(Of) -> gleam@dynamic@decode:one_of( begin gleam@dynamic@decode:field( <<"$ref"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Ref) -> castor@decodex:optional_field( <<"summary"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Summary) -> castor@decodex:optional_field( <<"description"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Description) -> gleam@dynamic@decode:success( {ref, Ref, Summary, Description} ) end ) end ) end ) end, [gleam@dynamic@decode:map(Of, fun(Field@0) -> {inline, Field@0} end)] ). -file("src/castor.gleam", 380). -spec non_empty_list_of_any_decoder() -> gleam@dynamic@decode:decoder(non_empty_list:non_empty_list(oas@generator@utils:any_())). non_empty_list_of_any_decoder() -> gleam@dynamic@decode:then( gleam@dynamic@decode:list(oas@generator@utils:any_decoder()), fun(List) -> case List of [] -> gleam@dynamic@decode:failure( {non_empty_list, null, []}, <<""/utf8>> ); [A | Rest] -> gleam@dynamic@decode:success({non_empty_list, A, Rest}) end end ). -file("src/castor.gleam", 388). -spec required_decoder() -> gleam@dynamic@decode:decoder(list(binary())). required_decoder() -> castor@decodex:default_field( <<"required"/utf8>>, gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ), [], fun gleam@dynamic@decode:success/1 ). -file("src/castor.gleam", 397). -spec nullable_decoder() -> gleam@dynamic@decode:decoder(boolean()). nullable_decoder() -> castor@decodex:default_field( <<"nullable"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_bool/1}, false, fun gleam@dynamic@decode:success/1 ). -file("src/castor.gleam", 117). -spec type_decoder() -> gleam@dynamic@decode:decoder({binary(), gleam@dynamic@decode:decoder(boolean())}). type_decoder() -> gleam@dynamic@decode:one_of( begin _pipe = {decoder, fun gleam@dynamic@decode:decode_string/1}, gleam@dynamic@decode:map( _pipe, fun(Type_) -> {Type_, nullable_decoder()} end ) end, [begin _pipe@1 = gleam@dynamic@decode:list( {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@dynamic@decode:then(_pipe@1, fun(Types) -> case Types of [Type_@1] -> gleam@dynamic@decode:success( {Type_@1, nullable_decoder()} ); [<<"null"/utf8>>, Type_@2] -> gleam@dynamic@decode:success( {Type_@2, gleam@dynamic@decode:success(true)} ); [Type_@2, <<"null"/utf8>>] -> gleam@dynamic@decode:success( {Type_@2, gleam@dynamic@decode:success(true)} ); _ -> gleam@dynamic@decode:failure( {<<""/utf8>>, nullable_decoder()}, <<"Type"/utf8>> ) end end) end] ). -file("src/castor.gleam", 401). -spec title_decoder() -> gleam@dynamic@decode:decoder(gleam@option:option(binary())). title_decoder() -> castor@decodex:optional_field( <<"title"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun gleam@dynamic@decode:success/1 ). -file("src/castor.gleam", 405). -spec description_decoder() -> gleam@dynamic@decode:decoder(gleam@option:option(binary())). description_decoder() -> castor@decodex:optional_field( <<"description"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun gleam@dynamic@decode:success/1 ). -file("src/castor.gleam", 409). -spec deprecated_decoder() -> gleam@dynamic@decode:decoder(boolean()). deprecated_decoder() -> castor@decodex:default_field( <<"deprecated"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_bool/1}, false, fun gleam@dynamic@decode:success/1 ). -file("src/castor.gleam", 414). ?DOC(" Construct a schema term requiring a boolean value.\n"). -spec boolean() -> schema(). boolean() -> {boolean, false, none, none, false}. -file("src/castor.gleam", 419). ?DOC(" Construct a schema term requiring an integer value.\n"). -spec integer() -> schema(). integer() -> {integer, none, none, none, none, none, false, none, none, false}. -file("src/castor.gleam", 434). ?DOC(" Construct a schema term requiring a float value.\n"). -spec number() -> schema(). number() -> {number, none, none, none, none, none, false, none, none, false}. -file("src/castor.gleam", 449). ?DOC(" Construct a schema term requiring a string value.\n"). -spec string() -> schema(). string() -> {string, none, none, none, none, false, none, none, false}. -file("src/castor.gleam", 463). ?DOC(" Construct a schema term requiring a null value.\n"). -spec null() -> schema(). null() -> {null, none, none, false}. -file("src/castor.gleam", 468). ?DOC(" Construct a schema term requiring an array value.\n"). -spec array(ref(schema())) -> schema(). array(Items) -> {array, none, none, false, Items, false, none, none, false}. -file("src/castor.gleam", 510). ?DOC(" Create a schema for an open dictionary of strings to the given schema type\n"). -spec dict(schema()) -> schema(). dict(Field_schema) -> {object, maps:new(), [], {some, {inline, Field_schema}}, none, 0, false, none, none, false}. -file("src/castor.gleam", 484). ?DOC( " Create a schema for an object with all properties defined.\n" " \n" " user `field` and `optional_field` to define fields.\n" ). -spec object(list({binary(), ref(schema()), boolean()})) -> schema(). object(Properties) -> {Properties@3, Required} = gleam@list:fold( Properties, {maps:new(), []}, fun(Acc, Property) -> {Properties@1, All_required} = Acc, {Key, Schema, Is_required} = Property, All_required@1 = case Is_required of true -> [Key | All_required]; false -> All_required end, Properties@2 = gleam@dict:insert(Properties@1, Key, Schema), {Properties@2, All_required@1} end ), {object, Properties@3, Required, none, none, 0, false, none, none, false}. -file("src/castor.gleam", 524). -spec enum_of_strings(non_empty_list:non_empty_list(binary())) -> schema(). enum_of_strings(Strings) -> {enum, non_empty_list:map(Strings, fun(Field@0) -> {string, Field@0} end)}. -file("src/castor.gleam", 529). ?DOC(" Construct a schema for a required field of an object.\n"). -spec field(FTK, FTL) -> {FTK, ref(FTL), boolean()}. field(Key, Schema) -> {Key, {inline, Schema}, true}. -file("src/castor.gleam", 534). ?DOC(" Construct a schema for an optional field of an object.\n"). -spec optional_field(FTN, FTO) -> {FTN, ref(FTO), boolean()}. optional_field(Key, Schema) -> {Key, {inline, Schema}, false}. -file("src/castor.gleam", 785). -spec json_object(list({binary(), gleam@option:option(gleam@json:json())})) -> gleam@json:json(). json_object(Properties) -> _pipe = gleam@list:filter_map( Properties, fun(Property) -> {Key, Value} = Property, case Value of {some, Value@1} -> {ok, {Key, Value@1}}; none -> {error, nil} end end ), gleam@json:object(_pipe). -file("src/castor.gleam", 961). -spec any_object(list({GBP, gleam@option:option(GBV)})) -> gleam@dict:dict(GBP, GBV). any_object(Properties) -> _pipe = gleam@list:filter_map( Properties, fun(Property) -> {Key, Value} = Property, case Value of {some, Value@1} -> {ok, {Key, Value@1}}; none -> {error, nil} end end ), maps:from_list(_pipe). -file("src/castor.gleam", 953). -spec ref_to_fields(ref(schema())) -> oas@generator@utils:any_(). ref_to_fields(Ref) -> case Ref of {inline, Schema} -> _pipe = to_fields(Schema), {object, _pipe}; {ref, Reference, _, _} -> {object, maps:from_list([{<<"$ref"/utf8>>, {string, Reference}}])} end. -file("src/castor.gleam", 798). ?DOC( " encode a schema to the fields of the json object.\n" " A schema will always be an object\n" ). -spec to_fields(schema()) -> gleam@dict:dict(binary(), oas@generator@utils:any_()). to_fields(Schema) -> case Schema of {boolean, Nullable, Title, Description, Deprecated} -> any_object( [{<<"type"/utf8>>, {some, {string, <<"boolean"/utf8>>}}}, {<<"nullable"/utf8>>, {some, {boolean, Nullable}}}, {<<"title"/utf8>>, gleam@option:map( Title, fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( Description, fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, Deprecated}}}] ); {integer, _, _, _, _, _, _, _, _, _} = Int -> any_object( [{<<"type"/utf8>>, {some, {string, <<"integer"/utf8>>}}}, {<<"multipleOf"/utf8>>, gleam@option:map( erlang:element(2, Int), fun(Field@0) -> {integer, Field@0} end )}, {<<"maximum"/utf8>>, gleam@option:map( erlang:element(3, Int), fun(Field@0) -> {integer, Field@0} end )}, {<<"exclusiveMaximum"/utf8>>, gleam@option:map( erlang:element(4, Int), fun(Field@0) -> {integer, Field@0} end )}, {<<"minimum"/utf8>>, gleam@option:map( erlang:element(5, Int), fun(Field@0) -> {integer, Field@0} end )}, {<<"exclusiveMinimum"/utf8>>, gleam@option:map( erlang:element(6, Int), fun(Field@0) -> {integer, Field@0} end )}, {<<"nullable"/utf8>>, {some, {boolean, erlang:element(7, Int)}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Int), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Int), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(10, Int)}}}] ); {number, _, _, _, _, _, _, _, _, _} = Number -> any_object( [{<<"type"/utf8>>, {some, {string, <<"number"/utf8>>}}}, {<<"multipleOf"/utf8>>, gleam@option:map( erlang:element(2, Number), fun(Field@0) -> {integer, Field@0} end )}, {<<"maximum"/utf8>>, gleam@option:map( erlang:element(3, Number), fun(Field@0) -> {number, Field@0} end )}, {<<"exclusiveMaximum"/utf8>>, gleam@option:map( erlang:element(4, Number), fun(Field@0) -> {number, Field@0} end )}, {<<"minimum"/utf8>>, gleam@option:map( erlang:element(5, Number), fun(Field@0) -> {number, Field@0} end )}, {<<"exclusiveMinimum"/utf8>>, gleam@option:map( erlang:element(6, Number), fun(Field@0) -> {number, Field@0} end )}, {<<"nullable"/utf8>>, {some, {boolean, erlang:element(7, Number)}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Number), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Number), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(10, Number)}}}] ); {string, _, _, _, _, _, _, _, _} = String -> any_object( [{<<"type"/utf8>>, {some, {string, <<"string"/utf8>>}}}, {<<"MaxLength"/utf8>>, gleam@option:map( erlang:element(2, String), fun(Field@0) -> {integer, Field@0} end )}, {<<"MinLength"/utf8>>, gleam@option:map( erlang:element(3, String), fun(Field@0) -> {integer, Field@0} end )}, {<<"Pattern"/utf8>>, gleam@option:map( erlang:element(4, String), fun(Field@0) -> {string, Field@0} end )}, {<<"Format"/utf8>>, gleam@option:map( erlang:element(5, String), fun(Field@0) -> {string, Field@0} end )}, {<<"nullable"/utf8>>, {some, {boolean, erlang:element(6, String)}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, String), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, String), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(9, String)}}}] ); {null, _, _, _} = Null -> any_object( [{<<"type"/utf8>>, {some, {string, <<"null"/utf8>>}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(2, Null), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(3, Null), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(4, Null)}}}] ); {array, _, _, _, _, _, _, _, _} = Array -> any_object( [{<<"type"/utf8>>, {some, {string, <<"array"/utf8>>}}}, {<<"maxItems"/utf8>>, gleam@option:map( erlang:element(2, Array), fun(Field@0) -> {integer, Field@0} end )}, {<<"minItems"/utf8>>, gleam@option:map( erlang:element(3, Array), fun(Field@0) -> {integer, Field@0} end )}, {<<"uniqueItems"/utf8>>, {some, {boolean, erlang:element(4, Array)}}}, {<<"items"/utf8>>, {some, ref_to_fields(erlang:element(5, Array))}}, {<<"nullable"/utf8>>, {some, {boolean, erlang:element(6, Array)}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, Array), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, Array), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(9, Array)}}}] ); {object, _, _, _, _, _, _, _, _, _} = Object -> any_object( [{<<"type"/utf8>>, {some, {string, <<"object"/utf8>>}}}, {<<"properties"/utf8>>, {some, {object, begin _pipe = erlang:element(2, Object), gleam@dict:map_values( _pipe, fun(_, V) -> ref_to_fields(V) end ) end}}}, {<<"additionalProperties"/utf8>>, gleam@option:map( erlang:element(4, Object), fun ref_to_fields/1 )}, {<<"maxProperties"/utf8>>, gleam@option:map( erlang:element(5, Object), fun(Field@0) -> {integer, Field@0} end )}, {<<"minProperties"/utf8>>, {some, {integer, erlang:element(6, Object)}}}, {<<"required"/utf8>>, {some, {array, gleam@list:map( erlang:element(3, Object), fun(Field@0) -> {string, Field@0} end )}}}, {<<"nullable"/utf8>>, {some, {boolean, erlang:element(7, Object)}}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Object), fun(Field@0) -> {string, Field@0} end )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Object), fun(Field@0) -> {string, Field@0} end )}, {<<"deprecated"/utf8>>, {some, {boolean, erlang:element(10, Object)}}}] ); {all_of, Varients} -> any_object( [{<<"allOf"/utf8>>, {some, {array, gleam@list:map( non_empty_list:to_list(Varients), fun ref_to_fields/1 )}}}] ); {any_of, Varients@1} -> any_object( [{<<"anyOf"/utf8>>, {some, {array, gleam@list:map( non_empty_list:to_list(Varients@1), fun ref_to_fields/1 )}}}] ); {one_of, Varients@2} -> any_object( [{<<"oneOf"/utf8>>, {some, {array, gleam@list:map( non_empty_list:to_list(Varients@2), fun ref_to_fields/1 )}}}] ); {enum, {non_empty_list, Value, []}} -> any_object([{<<"const"/utf8>>, {some, Value}}]); {enum, Values} -> Values@1 = non_empty_list:to_list(Values), any_object([{<<"enum"/utf8>>, {some, {array, Values@1}}}]); always_passes -> erlang:error(#{gleam_error => panic, message => <<"utils.Boolean(True)"/utf8>>, file => <>, module => <<"castor"/utf8>>, function => <<"to_fields"/utf8>>, line => 948}); always_fails -> erlang:error(#{gleam_error => panic, message => <<"utils.Boolean(False)"/utf8>>, file => <>, module => <<"castor"/utf8>>, function => <<"to_fields"/utf8>>, line => 949}) end. -file("src/castor.gleam", 778). -spec minimal_ref_encode(ref(schema())) -> gleam@json:json(). minimal_ref_encode(Ref) -> case Ref of {inline, Schema} -> encode_minimal(Schema); {ref, Reference, _, _} -> gleam@json:object([{<<"$ref"/utf8>>, gleam@json:string(Reference)}]) end. -file("src/castor.gleam", 672). ?DOC( " Encode schema with minimal optional properties.\n" " Compatible with AWS Bedrock Structured Output\n" " \n" " See https://aws.amazon.com/blogs/machine-learning/structured-outputs-on-amazon-bedrock-schema-compliant-ai-responses/\n" ). -spec encode_minimal(schema()) -> gleam@json:json(). encode_minimal(Schema) -> case Schema of {boolean, _, Title, Description, Deprecated} -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"boolean"/utf8>>)}}, {<<"title"/utf8>>, gleam@option:map(Title, fun gleam@json:string/1)}, {<<"description"/utf8>>, gleam@option:map(Description, fun gleam@json:string/1)}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(Deprecated)}}] ); {integer, _, _, _, _, _, _, _, _, _} = Int -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"integer"/utf8>>)}}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(7, Int))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Int), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Int), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(10, Int))}}] ); {number, _, _, _, _, _, _, _, _, _} = Number -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"number"/utf8>>)}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Number), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Number), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(10, Number))}}] ); {string, _, _, _, _, _, _, _, _} = String -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"string"/utf8>>)}}, {<<"Pattern"/utf8>>, gleam@option:map( erlang:element(4, String), fun gleam@json:string/1 )}, {<<"Format"/utf8>>, gleam@option:map( erlang:element(5, String), fun gleam@json:string/1 )}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, String), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, String), fun gleam@json:string/1 )}] ); {null, _, _, _} = Null -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"null"/utf8>>)}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(2, Null), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(3, Null), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(4, Null))}}] ); {array, _, _, _, _, _, _, _, _} = Array -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"array"/utf8>>)}}, {<<"items"/utf8>>, {some, minimal_ref_encode(erlang:element(5, Array))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, Array), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, Array), fun gleam@json:string/1 )}] ); {object, _, _, _, _, _, _, _, _, _} = Object -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"object"/utf8>>)}}, {<<"properties"/utf8>>, {some, gleam@json:dict( erlang:element(2, Object), fun(X) -> X end, fun minimal_ref_encode/1 )}}, {<<"additionalProperties"/utf8>>, {some, gleam@json:bool(false)}}, {<<"required"/utf8>>, {some, gleam@json:array( erlang:element(3, Object), fun gleam@json:string/1 )}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Object), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Object), fun gleam@json:string/1 )}] ); {all_of, Varients} -> json_object( [{<<"allOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients), fun minimal_ref_encode/1 )}}] ); {any_of, Varients@1} -> json_object( [{<<"anyOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients@1), fun minimal_ref_encode/1 )}}] ); {one_of, Varients@2} -> json_object( [{<<"oneOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients@2), fun minimal_ref_encode/1 )}}] ); {enum, {non_empty_list, Value, []}} -> json_object( [{<<"const"/utf8>>, {some, oas@generator@utils:any_to_json(Value)}}] ); {enum, Values} -> Values@1 = non_empty_list:to_list(Values), json_object( [{<<"enum"/utf8>>, {some, gleam@json:array( Values@1, fun oas@generator@utils:any_to_json/1 )}}] ); always_passes -> gleam@json:bool(true); always_fails -> gleam@json:bool(false) end. -file("src/castor.gleam", 771). -spec ref_encode(ref(schema())) -> gleam@json:json(). ref_encode(Ref) -> case Ref of {inline, Schema} -> encode(Schema); {ref, Reference, _, _} -> gleam@json:object([{<<"$ref"/utf8>>, gleam@json:string(Reference)}]) end. -file("src/castor.gleam", 541). ?DOC( " Convert a Schema to a gleam_json type. \n" " \n" " encode this to a string using `json.to_string`\n" ). -spec encode(schema()) -> gleam@json:json(). encode(Schema) -> case Schema of {boolean, Nullable, Title, Description, Deprecated} -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"boolean"/utf8>>)}}, {<<"nullable"/utf8>>, {some, gleam@json:bool(Nullable)}}, {<<"title"/utf8>>, gleam@option:map(Title, fun gleam@json:string/1)}, {<<"description"/utf8>>, gleam@option:map(Description, fun gleam@json:string/1)}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(Deprecated)}}] ); {integer, _, _, _, _, _, _, _, _, _} = Int -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"integer"/utf8>>)}}, {<<"multipleOf"/utf8>>, gleam@option:map( erlang:element(2, Int), fun gleam@json:int/1 )}, {<<"maximum"/utf8>>, gleam@option:map( erlang:element(3, Int), fun gleam@json:int/1 )}, {<<"exclusiveMaximum"/utf8>>, gleam@option:map( erlang:element(4, Int), fun gleam@json:int/1 )}, {<<"minimum"/utf8>>, gleam@option:map( erlang:element(5, Int), fun gleam@json:int/1 )}, {<<"exclusiveMinimum"/utf8>>, gleam@option:map( erlang:element(6, Int), fun gleam@json:int/1 )}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(7, Int))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Int), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Int), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(10, Int))}}] ); {number, _, _, _, _, _, _, _, _, _} = Number -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"number"/utf8>>)}}, {<<"multipleOf"/utf8>>, gleam@option:map( erlang:element(2, Number), fun gleam@json:int/1 )}, {<<"maximum"/utf8>>, gleam@option:map( erlang:element(3, Number), fun gleam@json:float/1 )}, {<<"exclusiveMaximum"/utf8>>, gleam@option:map( erlang:element(4, Number), fun gleam@json:float/1 )}, {<<"minimum"/utf8>>, gleam@option:map( erlang:element(5, Number), fun gleam@json:float/1 )}, {<<"exclusiveMinimum"/utf8>>, gleam@option:map( erlang:element(6, Number), fun gleam@json:float/1 )}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(7, Number))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Number), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Number), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(10, Number))}}] ); {string, _, _, _, _, _, _, _, _} = String -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"string"/utf8>>)}}, {<<"MaxLength"/utf8>>, gleam@option:map( erlang:element(2, String), fun gleam@json:int/1 )}, {<<"MinLength"/utf8>>, gleam@option:map( erlang:element(3, String), fun gleam@json:int/1 )}, {<<"Pattern"/utf8>>, gleam@option:map( erlang:element(4, String), fun gleam@json:string/1 )}, {<<"Format"/utf8>>, gleam@option:map( erlang:element(5, String), fun gleam@json:string/1 )}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(6, String))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, String), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, String), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(9, String))}}] ); {null, _, _, _} = Null -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"null"/utf8>>)}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(2, Null), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(3, Null), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(4, Null))}}] ); {array, _, _, _, _, _, _, _, _} = Array -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"array"/utf8>>)}}, {<<"maxItems"/utf8>>, gleam@option:map( erlang:element(2, Array), fun gleam@json:int/1 )}, {<<"minItems"/utf8>>, gleam@option:map( erlang:element(3, Array), fun gleam@json:int/1 )}, {<<"uniqueItems"/utf8>>, {some, gleam@json:bool(erlang:element(4, Array))}}, {<<"items"/utf8>>, {some, ref_encode(erlang:element(5, Array))}}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(6, Array))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(7, Array), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(8, Array), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(9, Array))}}] ); {object, _, _, _, _, _, _, _, _, _} = Object -> json_object( [{<<"type"/utf8>>, {some, gleam@json:string(<<"object"/utf8>>)}}, {<<"properties"/utf8>>, {some, gleam@json:dict( erlang:element(2, Object), fun(X) -> X end, fun ref_encode/1 )}}, {<<"additionalProperties"/utf8>>, gleam@option:map( erlang:element(4, Object), fun ref_encode/1 )}, {<<"maxProperties"/utf8>>, gleam@option:map( erlang:element(5, Object), fun gleam@json:int/1 )}, {<<"minProperties"/utf8>>, {some, gleam@json:int(erlang:element(6, Object))}}, {<<"required"/utf8>>, {some, gleam@json:array( erlang:element(3, Object), fun gleam@json:string/1 )}}, {<<"nullable"/utf8>>, {some, gleam@json:bool(erlang:element(7, Object))}}, {<<"title"/utf8>>, gleam@option:map( erlang:element(8, Object), fun gleam@json:string/1 )}, {<<"description"/utf8>>, gleam@option:map( erlang:element(9, Object), fun gleam@json:string/1 )}, {<<"deprecated"/utf8>>, {some, gleam@json:bool(erlang:element(10, Object))}}] ); {all_of, Varients} -> json_object( [{<<"allOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients), fun ref_encode/1 )}}] ); {any_of, Varients@1} -> json_object( [{<<"anyOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients@1), fun ref_encode/1 )}}] ); {one_of, Varients@2} -> json_object( [{<<"oneOf"/utf8>>, {some, gleam@json:array( non_empty_list:to_list(Varients@2), fun ref_encode/1 )}}] ); {enum, {non_empty_list, Value, []}} -> json_object( [{<<"const"/utf8>>, {some, oas@generator@utils:any_to_json(Value)}}] ); {enum, Values} -> Values@1 = non_empty_list:to_list(Values), json_object( [{<<"enum"/utf8>>, {some, gleam@json:array( Values@1, fun oas@generator@utils:any_to_json/1 )}}] ); always_passes -> gleam@json:bool(true); always_fails -> gleam@json:bool(false) end. -file("src/castor.gleam", 138). ?DOC( " Decoder for the JSON Schema type\n" " \n" " Use with `json.parse`\n" ). -spec decoder() -> gleam@dynamic@decode:decoder(schema()). decoder() -> gleam@dynamic@decode:recursive( fun() -> gleam@dynamic@decode:one_of( begin castor@decodex:discriminate( <<"type"/utf8>>, type_decoder(), {null, none, none, false}, fun(_use0) -> {Type_, Nullable_decoder} = _use0, case Type_ of <<"boolean"/utf8>> -> _pipe = begin gleam@dynamic@decode:then( Nullable_decoder, fun(Nullable) -> gleam@dynamic@decode:then( title_decoder(), fun(Title) -> gleam@dynamic@decode:then( description_decoder( ), fun(Description) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated ) -> gleam@dynamic@decode:success( {boolean, Nullable, Title, Description, Deprecated} ) end ) end ) end ) end ) end, {ok, _pipe}; <<"integer"/utf8>> -> _pipe@1 = begin castor@decodex:optional_field( <<"multipleOf"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Multiple_of) -> castor@decodex:optional_field( <<"maximum"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Maximum) -> castor@decodex:optional_field( <<"exclusiveMaximum"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun( Exclusive_maximum ) -> castor@decodex:optional_field( <<"minimum"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Minimum) -> castor@decodex:optional_field( <<"exclusiveMinimum"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun( Exclusive_minimum ) -> gleam@dynamic@decode:then( Nullable_decoder, fun( Nullable@1 ) -> gleam@dynamic@decode:then( title_decoder( ), fun( Title@1 ) -> gleam@dynamic@decode:then( description_decoder( ), fun( Description@1 ) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated@1 ) -> gleam@dynamic@decode:success( {integer, Multiple_of, Maximum, Exclusive_maximum, Minimum, Exclusive_minimum, Nullable@1, Title@1, Description@1, Deprecated@1} ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end, {ok, _pipe@1}; <<"number"/utf8>> -> _pipe@2 = begin castor@decodex:optional_field( <<"multipleOf"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Multiple_of@1) -> castor@decodex:optional_field( <<"maximum"/utf8>>, castor@decodex:number(), fun(Maximum@1) -> castor@decodex:optional_field( <<"exclusiveMaximum"/utf8>>, castor@decodex:number( ), fun( Exclusive_maximum@1 ) -> castor@decodex:optional_field( <<"minimum"/utf8>>, castor@decodex:number( ), fun( Minimum@1 ) -> castor@decodex:optional_field( <<"exclusiveMinimum"/utf8>>, castor@decodex:number( ), fun( Exclusive_minimum@1 ) -> gleam@dynamic@decode:then( Nullable_decoder, fun( Nullable@2 ) -> gleam@dynamic@decode:then( title_decoder( ), fun( Title@2 ) -> gleam@dynamic@decode:then( description_decoder( ), fun( Description@2 ) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated@2 ) -> gleam@dynamic@decode:success( {number, Multiple_of@1, Maximum@1, Exclusive_maximum@1, Minimum@1, Exclusive_minimum@1, Nullable@2, Title@2, Description@2, Deprecated@2} ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end, {ok, _pipe@2}; <<"string"/utf8>> -> _pipe@3 = begin castor@decodex:optional_field( <<"maxLength"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Max_length) -> castor@decodex:optional_field( <<"minLength"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Min_length) -> castor@decodex:optional_field( <<"pattern"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Pattern) -> castor@decodex:optional_field( <<"format"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_string/1}, fun(Format) -> gleam@dynamic@decode:then( Nullable_decoder, fun( Nullable@3 ) -> gleam@dynamic@decode:then( title_decoder( ), fun( Title@3 ) -> gleam@dynamic@decode:then( description_decoder( ), fun( Description@3 ) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated@3 ) -> gleam@dynamic@decode:success( {string, Max_length, Min_length, Pattern, Format, Nullable@3, Title@3, Description@3, Deprecated@3} ) end ) end ) end ) end ) end ) end ) end ) end ) end, {ok, _pipe@3}; <<"null"/utf8>> -> _pipe@4 = begin gleam@dynamic@decode:then( title_decoder(), fun(Title@4) -> gleam@dynamic@decode:then( description_decoder(), fun(Description@4) -> gleam@dynamic@decode:then( deprecated_decoder(), fun(Deprecated@4) -> gleam@dynamic@decode:success( {null, Title@4, Description@4, Deprecated@4} ) end ) end ) end ) end, {ok, _pipe@4}; <<"array"/utf8>> -> _pipe@5 = (begin castor@decodex:optional_field( <<"maxItems"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Max_items) -> castor@decodex:optional_field( <<"minItems"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun(Min_items) -> castor@decodex:default_field( <<"uniqueItems"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_bool/1}, false, fun(Unique_items) -> gleam@dynamic@decode:field( <<"items"/utf8>>, ref_decoder( decoder( ) ), fun(Items) -> gleam@dynamic@decode:then( Nullable_decoder, fun( Nullable@4 ) -> gleam@dynamic@decode:then( title_decoder( ), fun( Title@5 ) -> gleam@dynamic@decode:then( description_decoder( ), fun( Description@5 ) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated@5 ) -> gleam@dynamic@decode:success( {array, Max_items, Min_items, Unique_items, Items, Nullable@4, Title@5, Description@5, Deprecated@5} ) end ) end ) end ) end ) end ) end ) end ) end ) end), {ok, _pipe@5}; <<"object"/utf8>> -> _pipe@6 = begin castor@decodex:optional_field( <<"allOf"/utf8>>, non_empty_list_of_schema_decoder(), fun(All_of) -> case All_of of {some, Schemas} -> gleam@dynamic@decode:success( {all_of, Schemas} ); none -> gleam@dynamic@decode:then( properties_decoder(), fun(Properties) -> gleam@dynamic@decode:then( required_decoder( ), fun( Required ) -> castor@decodex:optional_field( <<"additionalProperties"/utf8>>, ref_decoder( decoder( ) ), fun( Additional_properties ) -> castor@decodex:optional_field( <<"maxProperties"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, fun( Max_properties ) -> castor@decodex:default_field( <<"minProperties"/utf8>>, {decoder, fun gleam@dynamic@decode:decode_int/1}, 0, fun( Min_properties ) -> gleam@dynamic@decode:then( Nullable_decoder, fun( Nullable@5 ) -> gleam@dynamic@decode:then( title_decoder( ), fun( Title@6 ) -> gleam@dynamic@decode:then( description_decoder( ), fun( Description@6 ) -> gleam@dynamic@decode:then( deprecated_decoder( ), fun( Deprecated@6 ) -> gleam@dynamic@decode:success( {object, Properties, Required, Additional_properties, Max_properties, Min_properties, Nullable@5, Title@6, Description@6, Deprecated@6} ) end ) end ) end ) end ) end ) end ) end ) end ) end ) end end ) end, {ok, _pipe@6}; Type_@1 -> {error, <<"valid schema type got: "/utf8, Type_@1/binary>>} end end ) end, [gleam@dynamic@decode:field( <<"allOf"/utf8>>, begin _pipe@7 = non_empty_list_of_schema_decoder(), gleam@dynamic@decode:map( _pipe@7, fun(Field@0) -> {all_of, Field@0} end ) end, fun gleam@dynamic@decode:success/1 ), gleam@dynamic@decode:field( <<"anyOf"/utf8>>, begin _pipe@8 = non_empty_list_of_schema_decoder(), gleam@dynamic@decode:map( _pipe@8, fun(Field@0) -> {any_of, Field@0} end ) end, fun gleam@dynamic@decode:success/1 ), gleam@dynamic@decode:field( <<"oneOf"/utf8>>, begin _pipe@9 = non_empty_list_of_schema_decoder(), gleam@dynamic@decode:map( _pipe@9, fun(Field@0) -> {one_of, Field@0} end ) end, fun gleam@dynamic@decode:success/1 ), gleam@dynamic@decode:field( <<"enum"/utf8>>, begin _pipe@10 = non_empty_list_of_any_decoder(), gleam@dynamic@decode:map( _pipe@10, fun(Field@0) -> {enum, Field@0} end ) end, fun gleam@dynamic@decode:success/1 ), gleam@dynamic@decode:field( <<"const"/utf8>>, begin _pipe@11 = oas@generator@utils:any_decoder(), gleam@dynamic@decode:map( _pipe@11, fun(Value) -> {enum, non_empty_list:single(Value)} end ) end, fun gleam@dynamic@decode:success/1 ), begin _pipe@12 = {decoder, fun gleam@dynamic@decode:decode_bool/1}, gleam@dynamic@decode:map(_pipe@12, fun(B) -> case B of true -> always_passes; false -> always_fails end end) end, begin _pipe@13 = gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, {decoder, fun gleam@dynamic@decode:decode_string/1} ), gleam@dynamic@decode:map( _pipe@13, fun(D) -> case D =:= maps:new() of true -> always_passes; false -> always_fails end end ) end] ) end ). -file("src/castor.gleam", 372). -spec non_empty_list_of_schema_decoder() -> gleam@dynamic@decode:decoder(non_empty_list:non_empty_list(ref(schema()))). non_empty_list_of_schema_decoder() -> gleam@dynamic@decode:then( gleam@dynamic@decode:list(ref_decoder(decoder())), fun(List) -> case List of [] -> gleam@dynamic@decode:failure( {non_empty_list, {inline, always_fails}, []}, <<""/utf8>> ); [A | Rest] -> gleam@dynamic@decode:success({non_empty_list, A, Rest}) end end ). -file("src/castor.gleam", 108). -spec properties_decoder() -> gleam@dynamic@decode:decoder(gleam@dict:dict(binary(), ref(schema()))). properties_decoder() -> castor@decodex:default_field( <<"properties"/utf8>>, gleam@dynamic@decode:dict( {decoder, fun gleam@dynamic@decode:decode_string/1}, ref_decoder(decoder()) ), maps:new(), fun gleam@dynamic@decode:success/1 ).