Current section
Files
Jump to
Current section
Files
src/tubes@msg.erl
-module(tubes@msg).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([parse/1]).
-export_type([irc_message/0, message_source/0]).
-type irc_message() :: {irc_message,
gleam@dict:dict(binary(), gleam@option:option(binary())),
gleam@option:option(message_source()),
binary(),
list(binary())}.
-type message_source() :: {server, binary()} |
{nick, binary(), binary(), binary()}.
-spec take_if_prefix(binary(), binary(), FQZ, fun((binary()) -> FQZ)) -> {FQZ,
binary()}.
take_if_prefix(Msg, Prefix, Default, Callback) ->
Msg@1 = gleam@string:trim_left(Msg),
case {gleam@string:first(Msg@1),
gleam@string:split_once(Msg@1, <<" "/utf8>>)} of
{{ok, P}, {ok, {X, Rest}}} when P =:= Prefix ->
Res = begin
_pipe = X,
_pipe@1 = gleam@string:drop_left(_pipe, 1),
Callback(_pipe@1)
end,
{Res, Rest};
{_, _} ->
{Default, Msg@1}
end.
-spec escape_tag(binary()) -> binary().
escape_tag(X) ->
_pipe = X,
_pipe@1 = gleam@string:replace(_pipe, <<"\\:"/utf8>>, <<";"/utf8>>),
_pipe@2 = gleam@string:replace(_pipe@1, <<"\\s"/utf8>>, <<" "/utf8>>),
_pipe@3 = gleam@string:replace(_pipe@2, <<"\\\\"/utf8>>, <<"\\"/utf8>>),
_pipe@4 = gleam@string:replace(_pipe@3, <<"\\r"/utf8>>, <<"\r"/utf8>>),
gleam@string:replace(_pipe@4, <<"\\n"/utf8>>, <<"\n"/utf8>>).
-spec parse_single_tag(binary()) -> {binary(), gleam@option:option(binary())}.
parse_single_tag(X) ->
case gleam@string:split_once(X, <<"="/utf8>>) of
{ok, {K, V}} ->
{escape_tag(K), {some, escape_tag(V)}};
{error, _} ->
{escape_tag(X), none}
end.
-spec parse_tags(binary()) -> gleam@dict:dict(binary(), gleam@option:option(binary())).
parse_tags(Tags) ->
_pipe = Tags,
_pipe@1 = gleam@string:split(_pipe, <<";"/utf8>>),
_pipe@2 = gleam@list:map(_pipe@1, fun parse_single_tag/1),
maps:from_list(_pipe@2).
-spec parse_source(binary()) -> gleam@option:option(message_source()).
parse_source(Source) ->
{some, case gleam@string:split_once(Source, <<"!"/utf8>>) of
{ok, {Nick, Rest}} ->
case gleam@string:split_once(Rest, <<"@"/utf8>>) of
{ok, {User, Host}} ->
{nick, Nick, User, Host};
_ ->
{server, Source}
end;
_ ->
{server, Source}
end}.
-spec parse_params(binary()) -> list(binary()).
parse_params(Params) ->
case {gleam@string:split_once(Params, <<" :"/utf8>>),
gleam@string:starts_with(Params, <<":"/utf8>>)} of
{{ok, {Rest, Long}}, _} ->
_pipe = gleam@string:split(Rest, <<" "/utf8>>),
lists:append(_pipe, [Long]);
{_, true} ->
[gleam@string:drop_left(Params, 1)];
{_, _} ->
_pipe@1 = gleam@string:split(Params, <<" "/utf8>>),
gleam@list:filter(_pipe@1, fun(X) -> X /= <<""/utf8>> end)
end.
-spec parse(binary()) -> irc_message().
parse(Msg) ->
{Tags, Msg@1} = take_if_prefix(
Msg,
<<"@"/utf8>>,
gleam@dict:new(),
fun parse_tags/1
),
{Source, Msg@2} = take_if_prefix(
Msg@1,
<<":"/utf8>>,
none,
fun parse_source/1
),
{Cmd, Msg@3} = begin
_pipe = gleam@string:split_once(Msg@2, <<" "/utf8>>),
gleam@result:unwrap(_pipe, {Msg@2, <<""/utf8>>})
end,
Params = parse_params(Msg@3),
{irc_message, Tags, Source, Cmd, Params}.