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