1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
mod conn; mod routes; mod web; extern crate futures; extern crate regex; #[macro_use] extern crate serde_derive; use conn::{conn_to_response, create_conn}; pub use conn::{html, json, xml, Conn}; use routes::match_route; pub use routes::{Middleware, Pattern, Route}; use std::collections::HashMap; use wasm_bindgen::prelude::*; pub use web::{Method, Request, Response}; pub enum ConfettiError {} pub async fn run(request_object: JsValue, routes: Vec<Route>) -> JsValue { let response = match process_request(request_object, routes).await { Ok(response) => response, Err(_) => Response { status: 400, body: "Invalid request".to_string(), headers: HashMap::new(), }, }; return JsValue::from_serde(&response).unwrap(); } async fn process_request(request_object: JsValue, routes: Vec<Route>) -> Result<Response, JsValue> { let request: Request = request_object.into_serde().map_err(|e| e.to_string())?; let conn = create_conn(request); let path = conn.path.clone(); let method = conn.method.clone(); match match_route(&routes, method, path) { None => Ok(Response { status: 404, body: "Not Found".to_string(), headers: HashMap::new(), }), Some(route) => match run_route(route, conn).await { Ok(conn) => Ok(conn_to_response(conn)), Err(_) => Ok(Response { status: 500, body: "Internal Server Error".to_string(), headers: HashMap::new(), }), }, } } async fn run_route(route: &Route, conn: Conn) -> Result<Conn, ConfettiError> { let mut current_conn: Conn = conn; let middlewares = &route.middlewares[..]; for middleware in middlewares { current_conn = (middleware.handler)(current_conn).await; if current_conn.halted { break; } } Ok(current_conn) }