Packages
mist
0.3.2
6.0.3
6.0.2
6.0.1
6.0.0
5.0.4
5.0.3
5.0.2
5.0.1
5.0.0
5.0.0-rc1
4.0.7
4.0.6
4.0.5
4.0.4
4.0.3
4.0.2
4.0.1
4.0.0
3.0.0
2.0.0
1.2.0
1.1.0
1.0.0
1.0.0-rc3
1.0.0-rc2
1.0.0-rc1
0.17.0
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.2
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.3
0.8.2
0.8.1
0.8.0
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.3
a misty Gleam web server
Current section
Files
Jump to
Current section
Files
src/mist@router.erl
-module(mist@router).
-compile(no_auto_import).
-export([new_state/0, validate_path/2, new/1, example_router/0]).
-export_type([route/1, router/0, http_handler/0, state/0]).
-type route(HIO) :: {route, binary(), http_handler()} | {gleam_phantom, HIO}.
-type router() :: {router, list(binary())}.
-type http_handler() :: {http1,
list(binary()),
fun((gleam@http@request:request(bitstring())) -> gleam@http@response:response(gleam@bit_builder:bit_builder()))} |
{websocket,
list(binary()),
fun((mist@websocket:message(), glisten@tcp:socket()) -> {ok, nil} |
{error, nil})}.
-type state() :: {state,
gleam@option:option(fun((mist@websocket:message(), glisten@tcp:socket()) -> {ok,
nil} |
{error, nil}))}.
-spec new_state() -> state().
new_state() ->
{state, none}.
-spec validate_path(list(binary()), list(binary())) -> {ok, nil} | {error, nil}.
validate_path(Path, Req) ->
case {Path, Req} of
{[<<"*"/utf8>> | _@1], _@2} ->
{ok, nil};
{[Expected], [Actual]} when Expected =:= Actual ->
{ok, nil};
{[Expected@1 | Path@1], [Actual@1 | Rest]} when Expected@1 =:= Actual@1 ->
validate_path(Path@1, Rest);
{_@3, _@4} ->
{error, nil}
end.
-spec new(list(http_handler())) -> fun((glisten@tcp:handler_message(), glisten@tcp:loop_state(state())) -> gleam@otp@actor:next(glisten@tcp:loop_state(state()))).
new(Routes) ->
glisten@tcp:handler(
fun(Msg, State) -> case erlang:element(2, erlang:element(4, State)) of
{some, Handler} ->
case mist@websocket:frame_from_message(Msg) of
{ok, {text_frame, _@1, Payload}} ->
_pipe = Payload,
_pipe@1 = {text_message, _pipe},
_pipe@2 = Handler(_pipe@1, erlang:element(2, State)),
_pipe@3 = gleam@result:replace(
_pipe@2,
{continue, State}
),
_pipe@4 = gleam@result:replace_error(
_pipe@3,
{stop, normal}
),
gleam@result:unwrap_both(_pipe@4);
{error, _@2} ->
{stop, normal}
end;
none ->
{ok, Req@1} = case mist@http:parse_request(
Msg,
erlang:element(2, State)
) of
{ok, Req} -> {ok, Req};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"mist/router"/utf8>>,
function => <<"new"/utf8>>,
line => 65})
end,
Matching_handler = begin
_pipe@5 = Routes,
gleam@list:find_map(_pipe@5, fun(Route) -> case Route of
{http1, Path, _@3} ->
_pipe@6 = Req@1,
_pipe@7 = gleam@http@request:path_segments(
_pipe@6
),
_pipe@8 = validate_path(Path, _pipe@7),
gleam@result:replace(_pipe@8, Route);
{websocket, Path, _@3} ->
_pipe@6 = Req@1,
_pipe@7 = gleam@http@request:path_segments(
_pipe@6
),
_pipe@8 = validate_path(Path, _pipe@7),
gleam@result:replace(_pipe@8, Route);
_@4 ->
{error, nil}
end end)
end,
case Matching_handler of
{ok, {websocket, _@5, Handler@1}} ->
_pipe@6 = Req@1,
_pipe@7 = mist@websocket:upgrade(
erlang:element(2, State),
_pipe@6
),
_pipe@8 = gleam@result:replace(
_pipe@7,
{continue,
erlang:setelement(
4,
State,
{state, {some, Handler@1}}
)}
),
_pipe@9 = gleam@result:replace_error(
_pipe@8,
{stop, normal}
),
gleam@result:unwrap_both(_pipe@9);
{ok, {http1, _@6, Handler@2}} ->
_pipe@10 = Req@1,
_pipe@11 = Handler@2(_pipe@10),
_pipe@12 = mist@http:to_bit_builder(_pipe@11),
_pipe@13 = glisten@tcp:send(
erlang:element(2, State),
_pipe@12
),
_pipe@14 = gleam@result:replace_error(_pipe@13, nil),
_pipe@15 = gleam@result:replace(
_pipe@14,
{stop, normal}
),
gleam@result:unwrap(_pipe@15, {stop, normal});
{error, _@7} ->
_pipe@16 = gleam@http@response:new(404),
_pipe@17 = gleam@http@response:set_body(
_pipe@16,
gleam@bit_builder:from_bit_string(<<""/utf8>>)
),
_pipe@18 = mist@http:to_bit_builder(_pipe@17),
_pipe@19 = glisten@tcp:send(
erlang:element(2, State),
_pipe@18
),
_pipe@20 = gleam@result:replace_error(_pipe@19, nil),
_pipe@21 = gleam@result:replace(
_pipe@20,
{stop, normal}
),
gleam@result:unwrap(_pipe@21, {stop, normal})
end
end end
).
-spec example_router() -> fun((glisten@tcp:handler_message(), glisten@tcp:loop_state(state())) -> gleam@otp@actor:next(glisten@tcp:loop_state(state()))).
example_router() ->
new(
[{http1,
[<<"home"/utf8>>],
fun(_) ->
_pipe = gleam@http@response:new(200),
gleam@http@response:set_body(
_pipe,
gleam@bit_builder:from_bit_string(<<"sup home boy"/utf8>>)
)
end},
{websocket,
[<<"echo"/utf8>>, <<"test"/utf8>>],
fun mist@websocket:echo_handler/2},
{http1,
[<<"*"/utf8>>],
fun(_) ->
_pipe@1 = gleam@http@response:new(200),
gleam@http@response:set_body(
_pipe@1,
gleam@bit_builder:from_bit_string(<<"Hello, world!"/utf8>>)
)
end}]
).