Current section
Files
Jump to
Current section
Files
src/castor.erl
-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 => <<?FILEPATH/utf8>>,
module => <<"castor"/utf8>>,
function => <<"to_fields"/utf8>>,
line => 948});
always_fails ->
erlang:error(#{gleam_error => panic,
message => <<"utils.Boolean(False)"/utf8>>,
file => <<?FILEPATH/utf8>>,
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
).