Packages

A Gleam library for interacting with the Discord API

Current section

Files

Jump to
shimmer src shimmer@ws@event_loop.erl
Raw

src/shimmer@ws@event_loop.erl

-module(shimmer@ws@event_loop).
-compile(no_auto_import).
-export([websocket_actor/1]).
-export_type([message/0, identify_info/0, state/0, spec/0]).
-type message() :: heartbeat_now | {frame, binary()}.
-type identify_info() :: {identify_info, binary(), integer()}.
-type state() :: {state,
integer(),
integer(),
nerf@websocket:connection(),
identify_info()}.
-type spec() :: {spec, fun(() -> state()), fun((message(), state()) -> state())}.
-spec heartbeat(state()) -> state().
heartbeat(State) ->
_@1 = erlang:send_after(
erlang:element(2, State),
gleam@otp@process:self(),
heartbeat_now
),
case gleam@int:compare(erlang:element(3, State), -1) of
gt ->
shimmer@ws@ws_utils:gateway_heartbeat(
erlang:element(3, State),
erlang:element(4, State)
);
_@2 ->
shimmer@ws@ws_utils:gateway_heartbeat_null(erlang:element(4, State))
end,
State.
-spec handle_hello(shimmer@ws@packet:hello_packet_data(), state()) -> state().
handle_hello(Data, State) ->
_@1 = erlang:send_after(0, gleam@otp@process:self(), heartbeat_now),
shimmer@ws@ws_utils:gateway_identify(
{identify_packet_data,
erlang:element(2, erlang:element(5, State)),
erlang:element(3, erlang:element(5, State)),
none},
erlang:element(4, State)
),
erlang:setelement(2, State, erlang:element(2, Data)).
-spec handle_error(shimmer@internal@error:shimmer_error(), state()) -> state().
handle_error(Error, State) ->
gleam@io:debug(Error),
State.
-spec handle_wrong_packet(shimmer@ws@packet:packet(), integer(), state()) -> state().
handle_wrong_packet(Packet, Expect_op, State) ->
_pipe = [<<"Error: Expected packet with opcode"/utf8>>,
gleam@int:to_string(Expect_op),
<<"but found a packet with opcode"/utf8>>,
gleam@int:to_string(erlang:element(2, Packet))],
_pipe@1 = gleam@string:join(_pipe, <<" "/utf8>>),
gleam@io:println(_pipe@1),
State.
-spec handle_frame(binary(), state()) -> state().
handle_frame(Frame, State) ->
case shimmer@ws@ws_utils:ws_frame_to_packet(Frame) of
{ok, Packet} ->
case erlang:element(2, Packet) of
0 ->
case erlang:element(4, Packet) of
{some, Event} ->
case Event of
E ->
gleam@io:println(
begin
_pipe = <<"Unknown Event: "/utf8>>,
gleam@string:append(_pipe, E)
end
),
State
end;
none ->
State
end;
10 ->
case Packet of
{hello_packet, _@1, _@2, _@3, Packet_data} ->
handle_hello(Packet_data, State);
_@4 ->
_pipe@1 = Packet,
handle_wrong_packet(_pipe@1, 10, State)
end;
11 ->
gleam@io:println(<<"Heartbeat Ack"/utf8>>),
State;
_@5 ->
gleam@io:println(
begin
_pipe@2 = <<"Unknown Packet ["/utf8>>,
_pipe@3 = gleam@string:append(
_pipe@2,
gleam@int:to_string(erlang:element(2, Packet))
),
_pipe@4 = gleam@string:append(
_pipe@3,
<<"] "/utf8>>
),
gleam@string:append(_pipe@4, Frame)
end
),
State
end;
{error, Err} ->
gleam@io:println(
begin
_pipe@5 = <<"Invalid Packet "/utf8>>,
gleam@string:append(_pipe@5, Frame)
end
),
handle_error(Err, State)
end.
-spec handle_message(message(), state()) -> state().
handle_message(Msg, State) ->
case Msg of
heartbeat_now ->
heartbeat(State);
{frame, Frame} ->
handle_frame(Frame, State)
end.
-spec websocket_actor(identify_info()) -> {ok, gleam@otp@process:pid_()} |
{error, gleam@dynamic:dynamic()}.
websocket_actor(Identify_info) ->
shimmer_event_loop:start_link(
{spec,
fun() ->
{ok, Conn@1} = case shimmer@ws@ws_utils:open_gateway() of
{ok, Conn} -> {ok, Conn};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"shimmer/ws/event_loop"/utf8>>,
function => <<"websocket_actor"/utf8>>,
line => 145})
end,
{state, 41250, -1, Conn@1, Identify_info}
end,
fun handle_message/2}
).