-module(glsql@error). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/glsql/error.gleam"). -export([render/3]). -export_type([error/0]). -type error() :: {lex_error, binary(), integer()} | {parse_error, binary(), integer(), gleam@option:option(binary())} | {unknown_statement, binary(), integer(), gleam@option:option(binary())} | {unknown_type, binary(), integer(), gleam@option:option(binary())} | {validation_error, binary(), integer(), gleam@option:option(binary())} | {config_error, binary(), gleam@option:option(binary())} | {io_error, binary()}. -file("src/glsql/error.gleam", 58). -spec render_hint(gleam@option:option(binary())) -> binary(). render_hint(Hint) -> case Hint of none -> <<""/utf8>>; {some, H} -> <<<<"\nHint: did you mean `"/utf8, H/binary>>/binary, "`?\n"/utf8>> end. -file("src/glsql/error.gleam", 51). -spec header(binary(), binary()) -> binary(). header(Title, Message) -> case Message of <<""/utf8>> -> <<<<"error: "/utf8, Title/binary>>/binary, "\n"/utf8>>; _ -> <<<<<<<<"error: "/utf8, Title/binary>>/binary, "\n"/utf8>>/binary, Message/binary>>/binary, "\n"/utf8>> end. -file("src/glsql/error.gleam", 98). -spec nth_line(binary(), integer()) -> binary(). nth_line(Source, Line) -> case begin _pipe = Source, _pipe@1 = gleam@string:split(_pipe, <<"\n"/utf8>>), _pipe@2 = gleam@list:drop(_pipe@1, Line - 1), gleam@list:first(_pipe@2) end of {ok, L} -> L; {error, nil} -> <<""/utf8>> end. -file("src/glsql/error.gleam", 87). -spec line_col(binary(), integer()) -> {integer(), integer()}. line_col(Source, Pos) -> Before = gleam@string:slice(Source, 0, Pos), Lines = gleam@string:split(Before, <<"\n"/utf8>>), Line = erlang:length(Lines), Col = case gleam@list:last(Lines) of {ok, L} -> string:length(L) + 1; {error, nil} -> 1 end, {Line, Col}. -file("src/glsql/error.gleam", 65). -spec parts(error()) -> {binary(), binary(), gleam@option:option(integer()), gleam@option:option(binary())}. parts(Err) -> case Err of {lex_error, M, Pos} -> {<<"Syntax error"/utf8>>, M, {some, Pos}, none}; {parse_error, M@1, Pos@1, Hint} -> {<<"Syntax error"/utf8>>, M@1, {some, Pos@1}, Hint}; {unknown_statement, W, Pos@2, Hint@1} -> {<<"Unknown statement"/utf8>>, <<<<"I don't know the statement `"/utf8, W/binary>>/binary, "`"/utf8>>, {some, Pos@2}, Hint@1}; {unknown_type, N, Pos@3, Hint@2} -> {<<"Unknown type"/utf8>>, <<<<"I have no Gleam mapping for the SQL type `"/utf8, N/binary>>/binary, "`"/utf8>>, {some, Pos@3}, Hint@2}; {validation_error, M@2, Pos@4, Hint@3} -> {<<"Invalid schema"/utf8>>, M@2, {some, Pos@4}, Hint@3}; {config_error, M@3, Hint@4} -> {<<"Invalid configuration"/utf8>>, M@3, none, Hint@4}; {io_error, M@4} -> {<<"File error"/utf8>>, M@4, none, none} end. -file("src/glsql/error.gleam", 16). -spec render(error(), binary(), binary()) -> binary(). render(Err, Filename, Source) -> {Title, Message, Position, Hint} = parts(Err), case Position of none -> <<(header(Title, Message))/binary, (render_hint(Hint))/binary>>; {some, Pos} -> {Line, Col} = line_col(Source, Pos), Text = nth_line(Source, Line), Gutter = erlang:integer_to_binary(Line), Pad = gleam@string:repeat(<<" "/utf8>>, string:length(Gutter)), <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<(header( Title, <<""/utf8>> ))/binary, Pad/binary>>/binary, "┌─ "/utf8>>/binary, Filename/binary>>/binary, ":"/utf8>>/binary, (erlang:integer_to_binary( Line ))/binary>>/binary, ":"/utf8>>/binary, (erlang:integer_to_binary( Col ))/binary>>/binary, "\n"/utf8>>/binary, Pad/binary>>/binary, " │\n"/utf8>>/binary, Gutter/binary>>/binary, " │ "/utf8>>/binary, Text/binary>>/binary, "\n"/utf8>>/binary, Pad/binary>>/binary, " │ "/utf8>>/binary, (gleam@string:repeat(<<" "/utf8>>, Col - 1))/binary>>/binary, "^ "/utf8>>/binary, Message/binary>>/binary, "\n"/utf8>>/binary, (render_hint(Hint))/binary>> end.