-module(handles@internal@tokenizer). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([run/3]). -export_type([token/0]). -type token() :: {constant, integer(), binary()} | {property, integer(), list(binary())} | {partial, integer(), binary(), list(binary())} | {if_block_start, integer(), list(binary())} | {if_block_end, integer()} | {unless_block_start, integer(), list(binary())} | {unless_block_end, integer()} | {each_block_start, integer(), list(binary())} | {each_block_end, integer()}. -spec split_body(binary()) -> list(binary()). split_body(Body) -> _pipe = Body, _pipe@1 = gleam@string:trim(_pipe), _pipe@2 = gleam@string:split(_pipe@1, <<" "/utf8>>), gleam@list:filter( _pipe@2, fun(It) -> begin _pipe@3 = It, _pipe@4 = gleam@string:trim(_pipe@3), gleam@string:length(_pipe@4) end > 0 end ). -spec split_arg(binary()) -> list(binary()). split_arg(Arg) -> case begin _pipe = Arg, gleam@string:trim(_pipe) end of <<"."/utf8>> -> []; Arg@1 -> gleam@string:split(Arg@1, <<"."/utf8>>) end. -spec capture_tag_body(binary(), integer()) -> {ok, {binary(), binary()}} | {error, handles@error:tokenizer_error()}. capture_tag_body(Input, Index) -> _pipe = Input, _pipe@1 = gleam@string:split_once(_pipe, <<"}}"/utf8>>), gleam@result:map_error(_pipe@1, fun(_) -> {unbalanced_tag, Index + 2} end). -spec run(binary(), integer(), list(token())) -> {ok, list(token())} | {error, handles@error:tokenizer_error()}. run(Input, Index, Tokens) -> case Input of <<"{{>"/utf8, Rest/binary>> -> gleam@result:'try'( capture_tag_body(Rest, Index), fun(_use0) -> {Body, Rest@1} = _use0, case split_body(Body) of [] -> {error, {missing_partial_id, Index + 2}}; [_] -> {error, {missing_argument, Index + 2}}; [Id, Arg] -> run( Rest@1, (Index + gleam@string:length(<<"{{>}}"/utf8>>)) + gleam@string:length(Body), [{partial, Index + 2, Id, split_arg(Arg)} | Tokens] ); _ -> {error, {unexpected_multiple_arguments, Index + 2}} end end ); <<"{{#"/utf8, Rest@2/binary>> -> gleam@result:'try'( capture_tag_body(Rest@2, Index), fun(_use0@1) -> {Body@1, Rest@3} = _use0@1, case split_body(Body@1) of [] -> {error, {missing_block_kind, Index + 2}}; [_] -> {error, {missing_argument, Index + 2}}; [Kind, Arg@1] -> case Kind of <<"if"/utf8>> -> run( Rest@3, (Index + 5) + gleam@string:length( Body@1 ), [{if_block_start, Index + 2, split_arg(Arg@1)} | Tokens] ); <<"unless"/utf8>> -> run( Rest@3, (Index + 5) + gleam@string:length( Body@1 ), [{unless_block_start, Index + 2, split_arg(Arg@1)} | Tokens] ); <<"each"/utf8>> -> run( Rest@3, (Index + 5) + gleam@string:length( Body@1 ), [{each_block_start, Index + 2, split_arg(Arg@1)} | Tokens] ); _ -> {error, {unexpected_block_kind, Index}} end; _ -> {error, {unexpected_multiple_arguments, Index + 2}} end end ); <<"{{/"/utf8, Rest@4/binary>> -> gleam@result:'try'( capture_tag_body(Rest@4, Index), fun(_use0@2) -> {Body@2, Rest@5} = _use0@2, case split_body(Body@2) of [] -> {error, {missing_block_kind, Index + 2}}; [_, _] -> {error, {unexpected_argument, Index + 2}}; [Kind@1] -> case Kind@1 of <<"if"/utf8>> -> run( Rest@5, (Index + 5) + gleam@string:length( Body@2 ), [{if_block_end, Index + 2} | Tokens] ); <<"unless"/utf8>> -> run( Rest@5, (Index + 5) + gleam@string:length( Body@2 ), [{unless_block_end, Index + 2} | Tokens] ); <<"each"/utf8>> -> run( Rest@5, (Index + 5) + gleam@string:length( Body@2 ), [{each_block_end, Index + 2} | Tokens] ); _ -> {error, {unexpected_block_kind, Index}} end; _ -> {error, {unexpected_argument, Index + 2}} end end ); <<"{{"/utf8, Rest@6/binary>> -> gleam@result:'try'( capture_tag_body(Rest@6, Index), fun(_use0@3) -> {Body@3, Rest@7} = _use0@3, case split_body(Body@3) of [] -> {error, {missing_argument, Index + 2}}; [Arg@2] -> run( Rest@7, (Index + 4) + gleam@string:length(Body@3), [{property, Index + 2, split_arg(Arg@2)} | Tokens] ); _ -> {error, {unexpected_multiple_arguments, Index + 2}} end end ); _ -> case begin _pipe = Input, gleam@string:split_once(_pipe, <<"{{"/utf8>>) end of {ok, {Str, Rest@8}} -> run( <<"{{"/utf8, Rest@8/binary>>, Index + gleam@string:length(Str), [{constant, Index, Str} | Tokens] ); _ -> case Input of <<""/utf8>> -> {ok, lists:reverse(Tokens)}; Str@1 -> {ok, lists:reverse( [{constant, Index, Str@1} | Tokens] )} end end end.