-module(oaisp@internal@package_interface).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/oaisp/internal/package_interface.gleam").
-export([decode_string/1, parse_format_lines/1, resolve_type/3, knows_module/2, malformed_format_lines/3]).
-export_type([error/0, resolved_type/0, field/0, field_type/0, format_directive/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(false).
-type error() :: {could_not_parse, gleam@json:decode_error()} |
{module_not_found, binary()} |
{type_not_found, binary(), binary()}.
-type resolved_type() :: {record_type,
list(field()),
gleam@option:option(binary())} |
{enum_type, list(binary()), gleam@option:option(binary())} |
{unmodelled, gleam@option:option(binary())}.
-type field() :: {field, binary(), field_type()}.
-type field_type() :: string_type |
int_type |
float_type |
bool_type |
nil_type |
{list_type, field_type()} |
{option_type, field_type()} |
{dict_type, field_type()} |
{tuple_type, list(field_type())} |
{formatted_string_type, binary()} |
timestamp_type |
{ref_type, binary(), binary()} |
any_type.
-type format_directive() :: {format_directive, binary(), binary()} |
{malformed_format, binary()}.
-file("src/oaisp/internal/package_interface.gleam", 87).
?DOC(false).
-spec decode_string(binary()) -> {ok, gleam@package_interface:package()} |
{error, error()}.
decode_string(Input) ->
_pipe = gleam@json:parse(Input, gleam@package_interface:decoder()),
gleam@result:map_error(
_pipe,
fun(Field@0) -> {could_not_parse, Field@0} end
).
-file("src/oaisp/internal/package_interface.gleam", 93).
?DOC(false).
-spec lookup_type(gleam@package_interface:package(), binary(), binary()) -> {ok,
gleam@package_interface:type_definition()} |
{error, error()}.
lookup_type(Package, Module, Name) ->
gleam@result:'try'(
begin
_pipe = gleam_stdlib:map_get(erlang:element(5, Package), Module),
gleam@result:replace_error(_pipe, {module_not_found, Module})
end,
fun(Found_module) ->
_pipe@1 = gleam_stdlib:map_get(
erlang:element(4, Found_module),
Name
),
gleam@result:replace_error(_pipe@1, {type_not_found, Module, Name})
end
).
-file("src/oaisp/internal/package_interface.gleam", 159).
?DOC(false).
-spec classify_union(
list(gleam@package_interface:type_constructor()),
gleam@option:option(binary())
) -> resolved_type().
classify_union(Constructors, Documentation) ->
case gleam@list:all(Constructors, fun(C) -> erlang:element(4, C) =:= [] end) of
true ->
{enum_type,
gleam@list:map(
Constructors,
fun(C@1) -> erlang:element(3, C@1) end
),
Documentation};
false ->
{unmodelled, Documentation}
end.
-file("src/oaisp/internal/package_interface.gleam", 186).
?DOC(false).
-spec apply_format(field_type(), binary()) -> field_type().
apply_format(Base, Format) ->
case Base of
string_type ->
{formatted_string_type, Format};
{option_type, string_type} ->
{option_type, {formatted_string_type, Format}};
Other ->
Other
end.
-file("src/oaisp/internal/package_interface.gleam", 225).
?DOC(false).
-spec nth_type(list(gleam@package_interface:type()), integer()) -> field_type().
nth_type(Parameters, Index) ->
case gleam@list:drop(Parameters, Index) of
[Type_ | _] ->
field_type(Type_);
[] ->
any_type
end.
-file("src/oaisp/internal/package_interface.gleam", 204).
?DOC(false).
-spec named_type(
binary(),
binary(),
binary(),
list(gleam@package_interface:type())
) -> field_type().
named_type(Name, Package, Module, Parameters) ->
case {Package, Module, Name} of
{<<""/utf8>>, <<"gleam"/utf8>>, <<"String"/utf8>>} ->
string_type;
{<<""/utf8>>, <<"gleam"/utf8>>, <<"Int"/utf8>>} ->
int_type;
{<<""/utf8>>, <<"gleam"/utf8>>, <<"Float"/utf8>>} ->
float_type;
{<<""/utf8>>, <<"gleam"/utf8>>, <<"Bool"/utf8>>} ->
bool_type;
{<<""/utf8>>, <<"gleam"/utf8>>, <<"Nil"/utf8>>} ->
nil_type;
{<<""/utf8>>, <<"gleam"/utf8>>, <<"List"/utf8>>} ->
{list_type, nth_type(Parameters, 0)};
{<<"gleam_stdlib"/utf8>>, <<"gleam/option"/utf8>>, <<"Option"/utf8>>} ->
{option_type, nth_type(Parameters, 0)};
{<<"gleam_stdlib"/utf8>>, <<"gleam/dict"/utf8>>, <<"Dict"/utf8>>} ->
{dict_type, nth_type(Parameters, 1)};
{<<"gleam_time"/utf8>>,
<<"gleam/time/timestamp"/utf8>>,
<<"Timestamp"/utf8>>} ->
timestamp_type;
{_, _, _} ->
{ref_type, Module, Name}
end.
-file("src/oaisp/internal/package_interface.gleam", 194).
?DOC(false).
-spec field_type(gleam@package_interface:type()) -> field_type().
field_type(Type_) ->
case Type_ of
{named, Name, Package, Module, Parameters} ->
named_type(Name, Package, Module, Parameters);
{tuple, Elements} ->
{tuple_type, gleam@list:map(Elements, fun field_type/1)};
{variable, _} ->
any_type;
{fn, _, _} ->
any_type
end.
-file("src/oaisp/internal/package_interface.gleam", 169).
?DOC(false).
-spec field_from_param(
gleam@package_interface:parameter(),
gleam@dict:dict(binary(), binary())
) -> field().
field_from_param(Parameter, Formats) ->
Label@1 = case erlang:element(2, Parameter) of
{some, Label} -> Label;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"record fields are checked to be labelled before this point"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"oaisp/internal/package_interface"/utf8>>,
function => <<"field_from_param"/utf8>>,
line => 173,
value => _assert_fail,
start => 6675,
'end' => 6715,
pattern_start => 6686,
pattern_end => 6697})
end,
Base = field_type(erlang:element(3, Parameter)),
Type_ = case gleam_stdlib:map_get(Formats, Label@1) of
{ok, Format} ->
apply_format(Base, Format);
{error, nil} ->
Base
end,
{field, Label@1, Type_}.
-file("src/oaisp/internal/package_interface.gleam", 140).
?DOC(false).
-spec classify_product(
gleam@package_interface:type_constructor(),
gleam@option:option(binary()),
gleam@dict:dict(binary(), binary())
) -> resolved_type().
classify_product(Constructor, Documentation, Formats) ->
case gleam@list:all(
erlang:element(4, Constructor),
fun(P) -> gleam@option:is_some(erlang:element(2, P)) end
) of
true ->
{record_type,
gleam@list:map(
erlang:element(4, Constructor),
fun(Parameter) -> field_from_param(Parameter, Formats) end
),
Documentation};
false ->
{unmodelled, Documentation}
end.
-file("src/oaisp/internal/package_interface.gleam", 300).
?DOC(false).
-spec parse_format_line(binary()) -> format_directive().
parse_format_line(Line) ->
Body = begin
_pipe = Line,
_pipe@1 = gleam@string:trim_start(_pipe),
_pipe@2 = gleam@string:drop_start(
_pipe@1,
string:length(<<"@format"/utf8>>)
),
gleam@string:trim(_pipe@2)
end,
case gleam@string:split_once(Body, <<":"/utf8>>) of
{ok, {Field, Format}} ->
Field@1 = gleam@string:trim(Field),
Format@1 = gleam@string:trim(Format),
case ((Field@1 =:= <<""/utf8>>) orelse (Format@1 =:= <<""/utf8>>))
orelse gleam_stdlib:contains_string(Field@1, <<" "/utf8>>) of
true ->
{malformed_format, gleam@string:trim(Line)};
false ->
{format_directive, Field@1, Format@1}
end;
{error, nil} ->
{malformed_format, gleam@string:trim(Line)}
end.
-file("src/oaisp/internal/package_interface.gleam", 282).
?DOC(false).
-spec is_format_line(binary()) -> boolean().
is_format_line(Line) ->
Rest = begin
_pipe = Line,
_pipe@1 = gleam@string:trim_start(_pipe),
gleam@string:split_once(_pipe@1, <<"@format"/utf8>>)
end,
case Rest of
{ok, {<<""/utf8>>, After}} ->
((After =:= <<""/utf8>>) orelse gleam_stdlib:string_starts_with(
After,
<<" "/utf8>>
))
orelse gleam_stdlib:string_starts_with(After, <<"\t"/utf8>>);
_ ->
false
end.
-file("src/oaisp/internal/package_interface.gleam", 276).
?DOC(false).
-spec parse_format_lines(list(binary())) -> list(format_directive()).
parse_format_lines(Lines) ->
_pipe = Lines,
_pipe@1 = gleam@list:filter(_pipe, fun is_format_line/1),
gleam@list:map(_pipe@1, fun parse_format_line/1).
-file("src/oaisp/internal/package_interface.gleam", 322).
?DOC(false).
-spec format_map(list(format_directive())) -> gleam@dict:dict(binary(), binary()).
format_map(Directives) ->
_pipe = Directives,
_pipe@1 = gleam@list:filter_map(_pipe, fun(Directive) -> case Directive of
{format_directive, Field, Format} ->
{ok, {Field, Format}};
{malformed_format, _} ->
{error, nil}
end end),
maps:from_list(_pipe@1).
-file("src/oaisp/internal/package_interface.gleam", 256).
?DOC(false).
-spec clean_doc(list(binary())) -> gleam@option:option(binary()).
clean_doc(Lines) ->
Cleaned = begin
_pipe = Lines,
_pipe@1 = gleam@list:filter(
_pipe,
fun(Line) -> not is_format_line(Line) end
),
_pipe@2 = gleam@string:join(_pipe@1, <<"\n"/utf8>>),
gleam@string:trim(_pipe@2)
end,
case Cleaned of
<<""/utf8>> ->
none;
_ ->
{some, Cleaned}
end.
-file("src/oaisp/internal/package_interface.gleam", 358).
?DOC(false).
-spec strip_one_leading_space(binary()) -> binary().
strip_one_leading_space(Line) ->
case gleam_stdlib:string_starts_with(Line, <<" "/utf8>>) of
true ->
gleam@string:drop_start(Line, 1);
false ->
Line
end.
-file("src/oaisp/internal/package_interface.gleam", 244).
?DOC(false).
-spec raw_doc_lines(gleam@option:option(binary())) -> list(binary()).
raw_doc_lines(Documentation) ->
case Documentation of
none ->
[];
{some, Text} ->
_pipe = Text,
_pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>),
gleam@list:map(_pipe@1, fun strip_one_leading_space/1)
end.
-file("src/oaisp/internal/package_interface.gleam", 125).
?DOC(false).
-spec classify(gleam@package_interface:type_definition()) -> resolved_type().
classify(Definition) ->
Raw = raw_doc_lines(erlang:element(2, Definition)),
Documentation = clean_doc(Raw),
Formats = format_map(parse_format_lines(Raw)),
case erlang:element(5, Definition) of
[] ->
{unmodelled, Documentation};
[Single] ->
classify_product(Single, Documentation, Formats);
Many ->
classify_union(Many, Documentation)
end.
-file("src/oaisp/internal/package_interface.gleam", 108).
?DOC(false).
-spec resolve_type(gleam@package_interface:package(), binary(), binary()) -> {ok,
resolved_type()} |
{error, error()}.
resolve_type(Package, Module, Name) ->
gleam@result:map(
lookup_type(Package, Module, Name),
fun(Definition) -> classify(Definition) end
).
-file("src/oaisp/internal/package_interface.gleam", 121).
?DOC(false).
-spec knows_module(gleam@package_interface:package(), binary()) -> boolean().
knows_module(Package, Module) ->
gleam@dict:has_key(erlang:element(5, Package), Module).
-file("src/oaisp/internal/package_interface.gleam", 338).
?DOC(false).
-spec malformed_format_lines(
gleam@package_interface:package(),
binary(),
binary()
) -> list(binary()).
malformed_format_lines(Package, Module, Name) ->
case lookup_type(Package, Module, Name) of
{error, _} ->
[];
{ok, Definition} ->
_pipe = erlang:element(2, Definition),
_pipe@1 = raw_doc_lines(_pipe),
_pipe@2 = parse_format_lines(_pipe@1),
gleam@list:filter_map(_pipe@2, fun(Directive) -> case Directive of
{malformed_format, Line} ->
{ok, Line};
{format_directive, _, _} ->
{error, nil}
end end)
end.