-module(glerd). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([generate/1, main/0]). -export_type([file_path/0, file_content/0, module_name/0, record_name/0, meta/0, meta_dict/0]). -type file_path() :: {file_path, binary()}. -type file_content() :: {file_content, binary()}. -type module_name() :: {module_name, binary()}. -type record_name() :: {record_name, binary()}. -type meta() :: {meta, binary()}. -type meta_dict() :: {meta_dict, gleam@dict:dict(record_name(), meta())}. -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 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@4 = gleam@iterator: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 => 61}) end, {file_path, Path@1} end ), _pipe@7 = gleam@iterator:map( _pipe@4, fun(File_path) -> _assert_subject = begin _pipe@5 = erlang:element(2, File_path), simplifile:read(_pipe@5) end, {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 => 65}) end, {File_path, begin _pipe@6 = Content, {file_content, _pipe@6} end} end ), _pipe@11 = gleam@iterator:map( _pipe@7, fun(Ctx) -> gluple@addition:with_append2( Ctx, fun(File_path@1, _) -> _pipe@8 = erlang:element(2, File_path@1), _pipe@9 = gleam@string:replace( _pipe@8, <>, <<""/utf8>> ), _pipe@10 = gleam@string:replace( _pipe@9, <<".gleam"/utf8>>, <<""/utf8>> ), {module_name, _pipe@10} end ) end ), _pipe@13 = gleam@iterator:map(_pipe@11, fun(Ctx@1) -> _pipe@12 = Ctx@1, gluple@removal:remove_first3(_pipe@12) end), _pipe@22 = gleam@iterator:map( _pipe@13, fun(Ctx@2) -> gluple@addition:with_append2( Ctx@2, fun(File_content, _) -> _pipe@14 = erlang:element(2, File_content), _pipe@15 = glexer:new(_pipe@14), _pipe@16 = glexer:lex(_pipe@15), _pipe@17 = gleam@list:window_by_2(_pipe@16), _pipe@21 = gleam@list:fold( _pipe@17, gleam@dict:new(), fun(Meta_dict, Pair) -> case Pair of {{{comment_doc, Meta}, {position, _}}, {{upper_name, Rec_name}, {position, _}}} -> gleam@dict:insert( Meta_dict, begin _pipe@18 = Rec_name, {record_name, _pipe@18} end, begin _pipe@19 = Meta, _pipe@20 = gleam@string:trim_left( _pipe@19 ), {meta, _pipe@20} end ); _ -> Meta_dict end end ), {meta_dict, _pipe@21} end ) end ), _pipe@24 = gleam@iterator:map( _pipe@22, fun(Ctx@3) -> gluple@addition:with_append3( Ctx@3, fun(File_content@1, _, _) -> _assert_subject@1 = begin _pipe@23 = erlang:element(2, File_content@1), glance:module(_pipe@23) end, {ok, Module} = 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 => 100}) 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 ) end ) end ), _pipe@26 = gleam@iterator:map(_pipe@24, fun(Ctx@4) -> _pipe@25 = Ctx@4, gluple@removal:remove_first4(_pipe@25) end), _pipe@31 = gleam@iterator:map( _pipe@26, fun(Ctx@5) -> {Module_name, Meta_dict@1, Variants@1} = Ctx@5, gleam@list:map( Variants@1, fun(_use0) -> {variant, Record_name, Fields} = _use0, Fields@1 = begin _pipe@27 = Fields, _pipe@28 = gleam@list:map( _pipe@27, fun(Field) -> {field, Field_name, Typ} = Field, _assert_subject@2 = gleam@option:'or'( Field_name, {some, <<"__none__"/utf8>>} ), {some, Field_name@1} = case _assert_subject@2 of {some, _} -> _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 => 115} ) end, <<<<<<<<"#(\""/utf8, Field_name@1/binary>>/binary, "\", "/utf8>>/binary, (field_type(Typ))/binary>>/binary, ")"/utf8>> end ), gleam@string:join(_pipe@28, <<","/utf8>>) end, _assert_subject@3 = begin _pipe@30 = gleam@dict:get( erlang:element(2, Meta_dict@1), begin _pipe@29 = Record_name, {record_name, _pipe@29} end ), gleam@result:'or'( _pipe@30, {ok, {meta, <<""/utf8>>}} ) end, {ok, {meta, Meta@1}} = case _assert_subject@3 of {ok, {meta, _}} -> _assert_subject@3; _assert_fail@4 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@4, module => <<"glerd"/utf8>>, function => <<"generate"/utf8>>, line => 119}) end, <<<<<<<<<<<<<<<<<<"#(\""/utf8, Record_name/binary>>/binary, "\",\""/utf8>>/binary, (erlang:element( 2, Module_name ))/binary>>/binary, "\","/utf8>>/binary, "["/utf8>>/binary, Fields@1/binary>>/binary, "],\""/utf8>>/binary, Meta@1/binary>>/binary, "\")"/utf8>> end ) end ), _pipe@33 = gleam@iterator:flat_map( _pipe@31, fun(Record_code) -> _pipe@32 = Record_code, gleam@iterator:from_list(_pipe@32) end ), gleam@iterator:fold( _pipe@33, <<""/utf8>>, fun(Acc, Record_code@1) -> <<<>/binary, ",\n"/utf8>> end ) end, Gen_file_path = <<<<"./"/utf8, Root/binary>>/binary, "/glerd_gen.gleam"/utf8>>, _assert_subject@4 = 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@4 of {ok, _} -> _assert_subject@4; _assert_fail@5 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@5, module => <<"glerd"/utf8>>, function => <<"generate"/utf8>>, line => 138}) end, _assert_subject@5 = gleamyshell_ffi:execute( <<"gleam"/utf8>>, <<"."/utf8>>, [<<"format"/utf8>>, Gen_file_path] ), {ok, _} = case _assert_subject@5 of {ok, _} -> _assert_subject@5; _assert_fail@6 -> erlang:error(#{gleam_error => let_assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail@6, module => <<"glerd"/utf8>>, function => <<"generate"/utf8>>, line => 148}) end, nil. -spec main() -> nil. main() -> generate(<<"src"/utf8>>).