Current section

Files

Jump to
glerd src glerd.erl
Raw

src/glerd.erl

-module(glerd).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([generate/1, main/0]).
-spec module_name_from_path(binary(), binary()) -> binary().
module_name_from_path(Root, Path) ->
_pipe = Path,
_pipe@1 = gleam@string:replace(
_pipe,
<<Root/binary, "/"/utf8>>,
<<""/utf8>>
),
gleam@string:replace(_pipe@1, <<".gleam"/utf8>>, <<""/utf8>>).
-spec ast_from_content(binary()) -> list(glance:variant()).
ast_from_content(Content) ->
_assert_subject = glance:module(Content),
{ok, Module} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glerd"/utf8>>,
function => <<"ast_from_content"/utf8>>,
line => 114})
end,
{module, _, Custom_types_definitions, _, _, _} = Module,
gleam@list:flat_map(
Custom_types_definitions,
fun(Custom_type_definition) ->
{definition, _, Custom_type} = Custom_type_definition,
{custom_type, _, _, _, _, Variants} = Custom_type,
Variants
end
).
-spec lexems_to_meta(binary(), list({glexer@token:token(), glexer:position()})) -> binary().
lexems_to_meta(Record_name, Lexems) ->
_assert_subject = begin
_pipe = Lexems,
_pipe@1 = gleam@list:window_by_2(_pipe),
_pipe@2 = gleam@list:find_map(_pipe@1, fun(Pair) -> case Pair of
{{{comment_doc, Meta}, {position, _}},
{{upper_name, Rec_name}, {position, _}}} when Rec_name =:= Record_name ->
{ok, Meta};
_ ->
{error, nil}
end end),
_pipe@3 = gleam@result:'or'(_pipe@2, {ok, <<""/utf8>>}),
gleam@result:map(_pipe@3, fun(S) -> _pipe@4 = S,
gleam@string:trim_left(_pipe@4) end)
end,
{ok, Meta@1} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glerd"/utf8>>,
function => <<"lexems_to_meta"/utf8>>,
line => 123})
end,
Meta@1.
-spec type_args(list(glance:type())) -> binary().
type_args(Types) ->
_pipe = Types,
_pipe@1 = gleam@list:map(_pipe, fun field_type/1),
_pipe@2 = gleam@list:intersperse(_pipe@1, <<","/utf8>>),
gleam@string:join(_pipe@2, <<""/utf8>>).
-spec field_type(glance:type()) -> binary().
field_type(Typ) ->
case Typ of
{named_type, Type_name, _, _} when Type_name =:= <<"String"/utf8>> ->
<<"types.IsString"/utf8>>;
{named_type, Type_name@1, _, _} when Type_name@1 =:= <<"Int"/utf8>> ->
<<"types.IsInt"/utf8>>;
{named_type, Type_name@2, _, _} when Type_name@2 =:= <<"Float"/utf8>> ->
<<"types.IsFloat"/utf8>>;
{named_type, Type_name@3, _, _} when Type_name@3 =:= <<"Bool"/utf8>> ->
<<"types.IsBool"/utf8>>;
{named_type, Type_name@4, _, [Typ@1]} when Type_name@4 =:= <<"List"/utf8>> ->
<<<<"types.IsList("/utf8, (field_type(Typ@1))/binary>>/binary,
")"/utf8>>;
{named_type, Type_name@5, _, [Key_type, Val_type]} when Type_name@5 =:= <<"Dict"/utf8>> ->
<<<<"types.IsDict("/utf8, (type_args([Key_type, Val_type]))/binary>>/binary,
")"/utf8>>;
{named_type, Type_name@6, _, [Typ@2]} when Type_name@6 =:= <<"Option"/utf8>> ->
<<<<"types.IsOption("/utf8, (field_type(Typ@2))/binary>>/binary,
")"/utf8>>;
{named_type, Type_name@7, _, [Typ1, Typ2]} when Type_name@7 =:= <<"Result"/utf8>> ->
<<<<"types.IsResult("/utf8, (type_args([Typ1, Typ2]))/binary>>/binary,
")"/utf8>>;
{tuple_type, [Typ1@1, Typ2@1]} ->
<<<<"types.IsTuple2("/utf8, (type_args([Typ1@1, Typ2@1]))/binary>>/binary,
")"/utf8>>;
{tuple_type, [Typ1@2, Typ2@2, Typ3]} ->
<<<<"types.IsTuple3("/utf8,
(type_args([Typ1@2, Typ2@2, Typ3]))/binary>>/binary,
")"/utf8>>;
{tuple_type, [Typ1@3, Typ2@3, Typ3@1, Typ4]} ->
<<<<"types.IsTuple4("/utf8,
(type_args([Typ1@3, Typ2@3, Typ3@1, Typ4]))/binary>>/binary,
")"/utf8>>;
{tuple_type, [Typ1@4, Typ2@4, Typ3@2, Typ4@1, Typ5]} ->
<<<<"types.IsTuple5("/utf8,
(type_args([Typ1@4, Typ2@4, Typ3@2, Typ4@1, Typ5]))/binary>>/binary,
")"/utf8>>;
{tuple_type, [Typ1@5, Typ2@5, Typ3@3, Typ4@2, Typ5@1, Typ6]} ->
<<<<"types.IsTuple6("/utf8,
(type_args([Typ1@5, Typ2@5, Typ3@3, Typ4@2, Typ5@1, Typ6]))/binary>>/binary,
")"/utf8>>;
{named_type, Record_name, _, _} ->
<<<<"types.IsRecord(\""/utf8, Record_name/binary>>/binary,
"\")"/utf8>>;
_ ->
<<"types.Unknown"/utf8>>
end.
-spec normalize_fields(list(glance:field(glance:type()))) -> binary().
normalize_fields(Fields) ->
_pipe = Fields,
_pipe@1 = gleam@list:map(
_pipe,
fun(Field) ->
{field, Field_name, Typ} = Field,
_assert_subject = gleam@option:'or'(
Field_name,
{some, <<"__none__"/utf8>>}
),
{some, Field_name@1} = case _assert_subject of
{some, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glerd"/utf8>>,
function => <<"normalize_fields"/utf8>>,
line => 143})
end,
<<<<<<<<"#(\""/utf8, Field_name@1/binary>>/binary, "\", "/utf8>>/binary,
(field_type(Typ))/binary>>/binary,
")"/utf8>>
end
),
gleam@string:join(_pipe@1, <<","/utf8>>).
-spec ast_to_code(binary(), binary(), binary()) -> list(binary()).
ast_to_code(Root, Path, Content) ->
Lexems = begin
_pipe = Content,
_pipe@1 = glexer:new(_pipe),
glexer:lex(_pipe@1)
end,
M = module_name_from_path(Root, Path),
Variants = ast_from_content(Content),
gleam@list:map(
Variants,
fun(_use0) ->
{variant, R, Fields} = _use0,
F = normalize_fields(Fields),
Mt = lexems_to_meta(R, Lexems),
<<<<<<<<<<<<<<<<<<"#(\""/utf8, R/binary>>/binary, "\",\""/utf8>>/binary,
M/binary>>/binary,
"\","/utf8>>/binary,
"["/utf8>>/binary,
F/binary>>/binary,
"],\""/utf8>>/binary,
Mt/binary>>/binary,
"\")"/utf8>>
end
).
-spec generate(binary()) -> nil.
generate(Root) ->
Records_info = begin
_pipe = fswalk:builder(),
_pipe@1 = fswalk:with_path(_pipe, Root),
_pipe@2 = fswalk:walk(_pipe@1),
_pipe@3 = gleam@iterator:filter(
_pipe@2,
fun(Entry_result) -> case Entry_result of
{ok, {entry, Path, {stat, Is_dir}}} ->
((Is_dir =:= false) andalso gleam@string:ends_with(
Path,
<<".gleam"/utf8>>
))
andalso not gleam_stdlib:contains_string(
Path,
<<"glerd_gen.gleam"/utf8>>
);
_ ->
false
end end
),
_pipe@5 = gleam@iterator:flat_map(
_pipe@3,
fun(Entry_result@1) ->
{ok, {entry, Path@1, _}} = case Entry_result@1 of
{ok, {entry, _, _}} -> Entry_result@1;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"glerd"/utf8>>,
function => <<"generate"/utf8>>,
line => 34})
end,
_assert_subject = simplifile:read(Path@1),
{ok, Content} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@1,
module => <<"glerd"/utf8>>,
function => <<"generate"/utf8>>,
line => 35})
end,
_pipe@4 = ast_to_code(Root, Path@1, Content),
gleam@iterator:from_list(_pipe@4)
end
),
gleam@iterator:fold(
_pipe@5,
<<""/utf8>>,
fun(Acc, El) -> <<<<Acc/binary, El/binary>>/binary, ",\n"/utf8>> end
)
end,
Gen_file_path = <<<<"./"/utf8, Root/binary>>/binary,
"/glerd_gen.gleam"/utf8>>,
_assert_subject@1 = simplifile:write(
Gen_file_path,
<<<<"// this file was generated via \"gleam run -m glerd\"
import glerd/types
pub const record_info = ["/utf8,
Records_info/binary>>/binary,
"]"/utf8>>
),
{ok, _} = case _assert_subject@1 of
{ok, _} -> _assert_subject@1;
_assert_fail@2 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@2,
module => <<"glerd"/utf8>>,
function => <<"generate"/utf8>>,
line => 43})
end,
_assert_subject@2 = gleamyshell_ffi:execute(
<<"gleam"/utf8>>,
<<"."/utf8>>,
[<<"format"/utf8>>, Gen_file_path]
),
{ok, _} = case _assert_subject@2 of
{ok, _} -> _assert_subject@2;
_assert_fail@3 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail@3,
module => <<"glerd"/utf8>>,
function => <<"generate"/utf8>>,
line => 53})
end,
nil.
-spec main() -> nil.
main() ->
generate(<<"src"/utf8>>).