Current section

Files

Jump to
oas_generator src oas@generator@lift.erl
Raw

src/oas@generator@lift.erl

-module(oas@generator@lift).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oas/generator/lift.gleam").
-export([content_id_to_type/1, content_id_to_fn_prefix/1, do_lift/2]).
-export_type([schema/1, fields/0, content_id/0, primitive/0]).
-type schema(PBU) :: {named, binary()} |
{primitive, primitive()} |
{array, schema(content_id())} |
{tuple, list(schema(content_id()))} |
{compound, PBU} |
{dictionary, schema(content_id())} |
unsupported.
-type fields() :: {fields,
list({binary(), {schema(content_id()), boolean()}}),
gleam@option:option(schema(content_id())),
list(binary())}.
-type content_id() :: {content_id, binary(), binary()}.
-type primitive() :: boolean | integer | number | string | null | always | never.
-file("src/oas/generator/lift.gleam", 86).
-spec pascal_case(content_id()) -> binary().
pascal_case(Id) ->
{content_id, First, Rest} = Id,
<<(string:uppercase(First))/binary, (string:lowercase(Rest))/binary>>.
-file("src/oas/generator/lift.gleam", 91).
-spec content_id_to_type(content_id()) -> binary().
content_id_to_type(Id) ->
<<"Anon"/utf8, (pascal_case(Id))/binary>>.
-file("src/oas/generator/lift.gleam", 95).
-spec content_id_to_fn_prefix(content_id()) -> binary().
content_id_to_fn_prefix(Id) ->
{content_id, First, Rest} = Id,
<<<<"anon_"/utf8, (string:lowercase(First))/binary>>/binary,
(string:lowercase(Rest))/binary>>.
-file("src/oas/generator/lift.gleam", 100).
-spec schema_to_string(schema(content_id())) -> binary().
schema_to_string(Schema) ->
case Schema of
{compound, Id} ->
pascal_case(Id);
{array, Items} ->
<<<<"Array("/utf8, (schema_to_string(Items))/binary>>/binary,
")"/utf8>>;
{dictionary, Field} ->
<<<<"Dict("/utf8, (schema_to_string(Field))/binary>>/binary,
")"/utf8>>;
{named, Name} ->
<<<<"Named("/utf8, Name/binary>>/binary, ")"/utf8>>;
{primitive, Primitive} ->
case Primitive of
boolean ->
<<"Boolean"/utf8>>;
integer ->
<<"Integer"/utf8>>;
number ->
<<"Number"/utf8>>;
string ->
<<"String"/utf8>>;
null ->
<<"Null"/utf8>>;
always ->
<<"Always"/utf8>>;
never ->
<<"Never"/utf8>>
end;
{tuple, Inner} ->
<<<<"Tuple("/utf8,
(begin
_pipe = gleam@list:map(Inner, fun schema_to_string/1),
gleam@string:join(_pipe, <<","/utf8>>)
end)/binary>>/binary,
")"/utf8>>;
unsupported ->
<<"Unsupported"/utf8>>
end.
-file("src/oas/generator/lift.gleam", 122).
-spec fields_to_content_id(fields()) -> content_id().
fields_to_content_id(Fields) ->
{fields, Named, Additional, Required} = Fields,
Id = begin
_pipe = gleam@list:map(
Named,
fun(Named_field) ->
{Name, {Schema, Nullable}} = Named_field,
<<<<Name/binary, (schema_to_string(Schema))/binary>>/binary,
(gleam@bool:to_string(Nullable))/binary>>
end
),
erlang:list_to_binary(_pipe)
end,
Additional@1 = case Additional of
{some, Schema@1} ->
schema_to_string(Schema@1);
none ->
<<""/utf8>>
end,
Required@1 = erlang:list_to_binary(Required),
Unique = <<<<Id/binary, Additional@1/binary>>/binary, Required@1/binary>>,
Hash = gleam@crypto:hash(sha256, <<Unique/binary>>),
Raw = gleam_stdlib:base16_encode(Hash),
First = gleam@string:slice(Raw, 0, 1),
Rest = gleam@string:slice(Raw, 1, 7),
{content_id, First, Rest}.
-file("src/oas/generator/lift.gleam", 146).
-spec not_top(schema(fields()), list({content_id(), fields()})) -> {schema(content_id()),
list({content_id(), fields()})}.
not_top(Top, Acc) ->
case Top of
{compound, Fields} ->
Id = fields_to_content_id(Fields),
Acc@1 = [{Id, Fields} | Acc],
{{compound, Id}, Acc@1};
{named, Name} ->
{{named, Name}, Acc};
{primitive, Primitive} ->
{{primitive, Primitive}, Acc};
{array, Items} ->
{{array, Items}, Acc};
{tuple, Items@1} ->
{{tuple, Items@1}, Acc};
{dictionary, Values} ->
{{dictionary, Values}, Acc};
unsupported ->
{unsupported, Acc}
end.
-file("src/oas/generator/lift.gleam", 277).
-spec do_all_map(list(PEP), fun((PEP) -> {ok, PFA} | {error, PEZ}), list(PFA)) -> {ok,
list(PFA)} |
{error, PEZ}.
do_all_map(Items, Func, Acc) ->
case Items of
[] ->
{ok, lists:reverse(Acc)};
[Item | Rest] ->
case Func(Item) of
{ok, Mapped} ->
do_all_map(Rest, Func, [Mapped | Acc]);
{error, Reason} ->
{error, Reason}
end
end.
-file("src/oas/generator/lift.gleam", 273).
-spec all_map(list(PFD), fun((PFD) -> {ok, PFG} | {error, PFF})) -> {ok,
list(PFG)} |
{error, PFF}.
all_map(Items, Func) ->
do_all_map(Items, Func, []).
-file("src/oas/generator/lift.gleam", 288).
-spec boolean_value(oas@generator@utils:any_()) -> {ok, boolean()} |
{error, nil}.
boolean_value(Any) ->
case Any of
{boolean, Value} ->
{ok, Value};
_ ->
{error, nil}
end.
-file("src/oas/generator/lift.gleam", 295).
-spec integer_value(oas@generator@utils:any_()) -> {ok, integer()} |
{error, nil}.
integer_value(Any) ->
case Any of
{integer, Value} ->
{ok, Value};
_ ->
{error, nil}
end.
-file("src/oas/generator/lift.gleam", 302).
-spec number_value(oas@generator@utils:any_()) -> {ok, float()} | {error, nil}.
number_value(Any) ->
case Any of
{number, Value} ->
{ok, Value};
_ ->
{error, nil}
end.
-file("src/oas/generator/lift.gleam", 309).
-spec string_value(oas@generator@utils:any_()) -> {ok, binary()} | {error, nil}.
string_value(Any) ->
case Any of
{string, Value} ->
{ok, Value};
_ ->
{error, nil}
end.
-file("src/oas/generator/lift.gleam", 164).
-spec do_lift(castor:ref(castor:schema()), list({content_id(), fields()})) -> {schema(fields()),
boolean(),
list({content_id(), fields()})}.
do_lift(Schema, Acc) ->
case Schema of
{ref, Ref, _, _} ->
{{named, Ref}, false, Acc};
{inline, Schema@1} ->
case Schema@1 of
{boolean, Nullable, _, _, _} ->
{{primitive, boolean}, Nullable, Acc};
{integer, _, _, _, _, _, Nullable@1, _, _, _} ->
{{primitive, integer}, Nullable@1, Acc};
{number, _, _, _, _, _, Nullable@2, _, _, _} ->
{{primitive, number}, Nullable@2, Acc};
{string, _, _, _, _, Nullable@3, _, _, _} ->
{{primitive, string}, Nullable@3, Acc};
{null, _, _, _} ->
{{primitive, null}, false, Acc};
{array, _, _, _, Items, Nullable@4, _, _, _} ->
{Top, _, Acc@1} = do_lift(Items, Acc),
{Schema@2, Acc@2} = not_top(Top, Acc@1),
{{array, Schema@2}, Nullable@4, Acc@2};
{object,
Properties,
Required,
Additional_properties,
_,
_,
Nullable@5,
_,
_,
_} ->
case {gleam@dict:is_empty(Properties),
Additional_properties} of
{true, {some, Values}} ->
{Top@1, _, Acc@3} = do_lift(Values, Acc),
{Schema@3, Acc@4} = not_top(Top@1, Acc@3),
{{dictionary, Schema@3}, Nullable@5, Acc@4};
{true, none} ->
{{primitive, null}, Nullable@5, Acc};
{_, _} ->
{Acc@8, Properties@1} = gleam@list:map_fold(
begin
_pipe = Properties,
maps:to_list(_pipe)
end,
Acc,
fun(Acc@5, Property) ->
{Field, Schema@4} = Property,
{Top@2, Nullable@6, Acc@6} = do_lift(
Schema@4,
Acc@5
),
{Schema@5, Acc@7} = not_top(Top@2, Acc@6),
{Acc@7, {Field, {Schema@5, Nullable@6}}}
end
),
{Additional, Acc@11} = case Additional_properties of
none ->
{none, Acc@8};
{some, {inline, always_fails}} ->
{none, Acc@8};
{some, Values@1} ->
{Top@3, _, Acc@9} = do_lift(Values@1, Acc@8),
{Schema@6, Acc@10} = not_top(Top@3, Acc@9),
{{some, Schema@6}, Acc@10}
end,
{{compound,
{fields, Properties@1, Additional, Required}},
Nullable@5,
Acc@11}
end;
{all_of, {non_empty_list, Schema@7, []}} ->
do_lift(Schema@7, Acc);
{all_of, Items@1} ->
{Acc@15, Items@2} = gleam@list:map_fold(
begin
_pipe@1 = Items@1,
non_empty_list:to_list(_pipe@1)
end,
Acc,
fun(Acc@12, Item) ->
{Top@4, _, Acc@13} = do_lift(Item, Acc@12),
{Schema@8, Acc@14} = not_top(Top@4, Acc@13),
{Acc@14, Schema@8}
end
),
{{tuple, Items@2}, false, Acc@15};
{any_of, {non_empty_list, Schema@9, []}} ->
do_lift(Schema@9, Acc);
{one_of, {non_empty_list, Schema@10, []}} ->
do_lift(Schema@10, Acc);
{any_of, _} ->
{unsupported, false, Acc};
{one_of, _} ->
{unsupported, false, Acc};
{enum, Items@3} ->
{non_empty_list, First, Rest} = Items@3,
case First of
{boolean, _} ->
case all_map(Rest, fun boolean_value/1) of
{ok, _} ->
{{primitive, boolean}, false, Acc};
{error, nil} ->
{unsupported, false, Acc}
end;
{integer, _} ->
case all_map(Rest, fun integer_value/1) of
{ok, _} ->
{{primitive, integer}, false, Acc};
{error, nil} ->
{unsupported, false, Acc}
end;
{number, _} ->
case all_map(Rest, fun number_value/1) of
{ok, _} ->
{{primitive, number}, false, Acc};
{error, nil} ->
{unsupported, false, Acc}
end;
{string, _} ->
case all_map(Rest, fun string_value/1) of
{ok, _} ->
{{primitive, string}, false, Acc};
{error, nil} ->
{unsupported, false, Acc}
end;
null ->
case Rest of
[] ->
{{primitive, null}, false, Acc};
_ ->
{unsupported, false, Acc}
end;
_ ->
{unsupported, false, Acc}
end;
always_passes ->
{{primitive, always}, false, Acc};
always_fails ->
{{primitive, never}, false, Acc}
end
end.