///|
/// Request payload for wasm runtime handlers
pub(all) struct WasmRequest {
request : @http.Request
body : String
}
///|
pub fn WasmRequest::new(
request : @http.Request,
body? : String = "",
) -> WasmRequest {
{ request, body }
}
///|
/// Response value produced by wasm runtime handlers
pub(all) struct WasmResponse {
status : Int
headers : Map[String, String]
body : String
} derive(Show, Eq)
///|
fn request_method_to_method(meth : @http.RequestMethod) -> @router.Method {
match meth {
Get => @router.Method::Get
Post => @router.Method::Post
Put => @router.Method::Put
Delete => @router.Method::Delete
Patch => @router.Method::Patch
Head => @router.Method::Head
Options => @router.Method::Options
Connect => @router.Method::Connect
Trace => @router.Method::Trace
}
}
///|
fn build_not_found_headers() -> Map[String, String] {
{ "Content-Type": "text/plain; charset=utf-8" }
}
///|
fn build_error_headers() -> Map[String, String] {
{ "Content-Type": "text/plain; charset=utf-8" }
}
///|
fn build_wasm_response(
status : Int,
body : String,
headers : Map[String, String],
) -> WasmResponse {
{ status, headers, body }
}
///|
pub type AppHandler = async (WasmRequest) -> WasmResponse
///|
/// Convert Server app to a platform handler function (wasm runtime)
pub fn Server::to_handler(self : Server) -> AppHandler {
self.to_handler_with_env(EmptyEnv::new(), ExecutionContext::new())
}
///|
/// Convert Server app to a platform handler function with environment and execution context (wasm runtime)
pub fn[E : Env, C : ExecCtx] Server::to_handler_with_env(
self : Server,
env : E,
exec_ctx : C,
) -> AppHandler {
async fn(input) {
let request = input.request
let meth = request_method_to_method(request.meth)
let state : Ref[WasmResponseState] = { val: WasmResponseState::new() }
let dispatch_result = self.match_and_dispatch(meth, request.path, fn(
params,
) {
Context::with_env(request, params, input.body, state, env, exec_ctx)
})
let dispatch = match dispatch_result {
RequestDispatchResult::NotFound =>
return build_wasm_response(404, "Not Found", build_not_found_headers())
RequestDispatchResult::Dispatched(d) => d
}
match dispatch_fallback_status(dispatch) {
Some(500) =>
return build_wasm_response(
500,
"Internal Server Error",
build_error_headers(),
)
Some(404) => ()
_ => ()
}
if state.val.sent {
build_wasm_response(state.val.status, state.val.body, state.val.headers)
} else {
build_wasm_response(404, "Not Found", build_not_found_headers())
}
}
}