mod conn;
mod filters;
mod routes;
mod web;
extern crate futures;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate uuid;
use conn::{conn_to_response, create_conn};
pub use conn::{html, json, xml, Conn};
pub use filters::{fetch_session, get_language};
use routes::match_route;
pub use routes::{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(current_conn).await;
if current_conn.halted {
break;
}
}
Ok(current_conn)
}