-module(roundabout). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/roundabout.gleam"). -export([parse_definitions/2, parse/1, main/2]). -export_type([segment/0, route/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 segment() :: {lit, binary()} | {str, binary()} | {int, binary()}. -type route() :: {route, binary(), list(segment()), list(route())}. -file("src/roundabout.gleam", 85). -spec assert_no_duplicate_variant_names(binary(), list(roundabout@node:node_())) -> {ok, list(roundabout@node:node_())} | {error, binary()}. assert_no_duplicate_variant_names(Parent_name, Nodes) -> Variant_names = gleam@list:map( Nodes, fun(Item) -> roundabout@type_name:snake( erlang:element(2, erlang:element(2, Item)) ) end ), As_set = gleam@set:from_list(Variant_names), case erlang:length(Variant_names) =:= gleam@set:size(As_set) of true -> {ok, Nodes}; false -> {error, <<<<"Route "/utf8, Parent_name/binary>>/binary, " contain duplicate route names"/utf8>>} end. -file("src/roundabout.gleam", 140). -spec assert_no_duplicate_segment_names(binary(), list(segment())) -> {ok, list(segment())} | {error, binary()}. assert_no_duplicate_segment_names(Node_name, Segments) -> Segment_names = gleam@list:filter_map(Segments, fun(Seg) -> case Seg of {lit, _} -> {error, nil}; {str, Val} -> {ok, justin:snake_case(Val)}; {int, Val@1} -> {ok, justin:snake_case(Val@1)} end end), As_set = gleam@set:from_list(Segment_names), case erlang:length(Segment_names) =:= gleam@set:size(As_set) of true -> {ok, Segments}; false -> {error, <<<<"Route "/utf8, Node_name/binary>>/binary, " contain duplicate segment names"/utf8>>} end. -file("src/roundabout.gleam", 108). -spec parse_definition_info(route()) -> {ok, roundabout@node:info()} | {error, binary()}. parse_definition_info(Input) -> gleam@result:'try'( assert_no_duplicate_segment_names( erlang:element(2, Input), erlang:element(3, Input) ), fun(Input_path) -> Path_result = begin _pipe = Input_path, gleam@list:try_map(_pipe, fun(Seg) -> case Seg of {lit, Val} -> _pipe@1 = roundabout@constant:new(Val), gleam@result:map( _pipe@1, fun(Field@0) -> {seg_lit, Field@0} end ); {str, Val@1} -> _pipe@2 = roundabout@parameter:new(Val@1, str), gleam@result:map( _pipe@2, fun(Field@0) -> {seg_param, Field@0} end ); {int, Val@2} -> _pipe@3 = roundabout@parameter:new(Val@2, int), gleam@result:map( _pipe@3, fun(Field@0) -> {seg_param, Field@0} end ) end end) end, gleam@result:'try'( roundabout@type_name:new(erlang:element(2, Input)), fun(Name) -> gleam@result:'try'( Path_result, fun(Path) -> _pipe@4 = {info, Name, Path}, {ok, _pipe@4} end ) end ) end ). -file("src/roundabout.gleam", 100). -spec parse_definition(route()) -> {ok, roundabout@node:node_()} | {error, binary()}. parse_definition(Definition) -> gleam@result:'try'( parse_definition_info(Definition), fun(Info) -> gleam@result:'try'( parse_definitions( erlang:element(2, Definition), erlang:element(4, Definition) ), fun(Sub) -> _pipe = {node, Info, Sub}, {ok, _pipe} end ) end ). -file("src/roundabout.gleam", 74). ?DOC(false). -spec parse_definitions(binary(), list(route())) -> {ok, list(roundabout@node:node_())} | {error, binary()}. parse_definitions(Parent_name, Definitions) -> gleam@result:'try'( gleam@list:try_map(Definitions, fun parse_definition/1), fun(Nodes) -> gleam@result:'try'( assert_no_duplicate_variant_names(Parent_name, Nodes), fun(Nodes@1) -> {ok, Nodes@1} end ) end ). -file("src/roundabout.gleam", 64). ?DOC(false). -spec parse(list(route())) -> {ok, roundabout@node:node_()} | {error, binary()}. parse(Definitions) -> gleam@result:'try'( parse_definitions(<<"root"/utf8>>, Definitions), fun(Sub) -> Root = {node, {info, roundabout@type_name:unsafe(<<""/utf8>>), []}, Sub}, {ok, Root} end ). -file("src/roundabout.gleam", 28). -spec main(list(route()), binary()) -> {ok, nil} | {error, binary()}. main(Definitions, Output_path) -> gleam@result:'try'( parse(Definitions), fun(Root) -> Types = roundabout@generate_types:generate_type_rec([], Root), Segments_to_route = roundabout@generate_segments_to_route:generate_segments_to_route_rec( [], Root ), Routes_to_path = roundabout@generate_route_to_path:generate_route_to_path_rec( [], Root ), Helpers = roundabout@generate_helpers:generate_helpers_rec([], Root), Utils = roundabout@generate_other:generate_utils(), All = glam@doc:concat( [roundabout@generate_other:generate_header(), roundabout@generate_other:generate_imports(), Types, Segments_to_route, Routes_to_path, Helpers, Utils] ), Generated_code = begin _pipe = All, glam@doc:to_string(_pipe, 80) end, Output_dir = filepath:directory_name(Output_path), _ = simplifile:create_directory_all(Output_dir), _ = simplifile:write(Output_path, Generated_code), {ok, nil} end ).