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