-module(handles@format). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([format_syntax_error/2, format_lex_error/2]). -export_type([position/0]). -type position() :: {position, integer(), integer(), integer()} | out_of_bounds. -spec resolve_position(binary(), integer(), position()) -> position(). resolve_position(Input, Target_index, Current) -> case Current of {position, Index, Row, Col} when Index =:= Target_index -> {position, Target_index, Row, Col}; {position, Index@1, Row@1, Col@1} -> case gleam@string:first(Input) of {ok, Char} -> case Char of <<"\n"/utf8>> -> resolve_position( gleam@string:drop_left(Input, 1), Target_index, {position, Index@1 + 1, Row@1 + 1, 0} ); _ -> resolve_position( gleam@string:drop_left(Input, 1), Target_index, {position, Index@1 + 1, Row@1, Col@1 + 1} ) end; {error, _} -> out_of_bounds end; out_of_bounds -> out_of_bounds end. -spec format_syntax_error(handles@lexer:syntax_error(), binary()) -> binary(). format_syntax_error(Error, Template) -> case Error of {missing_body, Start, _} -> case resolve_position(Template, Start, {position, 0, 0, 0}) of {position, _, Row, Col} -> gleam@string:concat( [<<"Tag is missing a body "/utf8>>, <<"(row="/utf8>>, gleam@int:to_string(Row), <<", col="/utf8>>, gleam@int:to_string(Col), <<")"/utf8>>] ); out_of_bounds -> erlang:error(#{gleam_error => panic, message => <<"Unable to resolve error position in template"/utf8>>, module => <<"handles/format"/utf8>>, function => <<"format_syntax_error"/utf8>>, line => 78}) end; {missing_block_kind, Start@1, _} -> case resolve_position(Template, Start@1, {position, 0, 0, 0}) of {position, _, Row@1, Col@1} -> gleam@string:concat( [<<"Tag is of unknown block kind "/utf8>>, <<"(row="/utf8>>, gleam@int:to_string(Row@1), <<", col="/utf8>>, gleam@int:to_string(Col@1), <<")"/utf8>>] ); out_of_bounds -> erlang:error(#{gleam_error => panic, message => <<"Unable to resolve error position in template"/utf8>>, module => <<"handles/format"/utf8>>, function => <<"format_syntax_error"/utf8>>, line => 91}) end; {unexpected_block_argument, Start@2, _} -> case resolve_position(Template, Start@2, {position, 0, 0, 0}) of {position, _, Row@2, Col@2} -> gleam@string:concat( [<<"Tag is a closing block, which does not take any arguments "/utf8>>, <<"(row="/utf8>>, gleam@int:to_string(Row@2), <<", col="/utf8>>, gleam@int:to_string(Col@2), <<")"/utf8>>] ); out_of_bounds -> erlang:error(#{gleam_error => panic, message => <<"Unable to resolve error position in template"/utf8>>, module => <<"handles/format"/utf8>>, function => <<"format_syntax_error"/utf8>>, line => 104}) end end. -spec format_lex_error(handles@lexer:lex_error(), binary()) -> binary(). format_lex_error(Error, Template) -> case Error of {unbalanced_tag, Index, _} -> case resolve_position(Template, Index, {position, 0, 0, 0}) of {position, _, Row, Col} -> gleam@string:concat( [<<"Tag is missing closing braces }} "/utf8>>, <<"(row="/utf8>>, gleam@int:to_string(Row), <<", col="/utf8>>, gleam@int:to_string(Col), <<")"/utf8>>] ); out_of_bounds -> erlang:error(#{gleam_error => panic, message => <<"Unable to resolve error position in template"/utf8>>, module => <<"handles/format"/utf8>>, function => <<"format_lex_error"/utf8>>, line => 55}) end; {syntax_error, Errors} -> _pipe = Errors, gleam@list:fold( _pipe, <<""/utf8>>, fun(Acc, Err) -> gleam@string:concat( [Acc, <<"\n"/utf8>>, format_syntax_error(Err, Template)] ) end ) end.