Packages

Handles is a templating language written in pure Gleam. Heavily inspired by Mustache and Handlebars.js

Current section

Files

Jump to
handles src handles@format.erl
Raw

src/handles@format.erl

-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.