use std::net::SocketAddr; use std::pin::Pin; use std::sync::Arc; use axum::handler::HandlerWithoutStateExt; use axum::response::IntoResponse; use std::error::Error; use tokio::net::TcpListener; pub type AnyError = Box; pub type Result = core::result::Result; pub type Dbs = atelier::rusqlite_thread_pool::PoolSender; fn migrate(connection: &mut rusqlite::Connection) -> Result<()> { Ok(()) } fn init(connection: &mut rusqlite::Connection) -> rusqlite::Result<()> { Ok(()) } type Request = axum::extract::Request; type Response = axum::response::Response; type Handler = Box< dyn Fn(Request) -> Pin + Send + 'static>> + Send + Sync + 'static, >; type Router = atelier::router::Router; fn make_handler(f: F) -> Handler where Fut: Future + Send + 'static, F: FnMut(Request) -> Fut + Clone + Send + Sync + 'static, { Box::new(move |req| { let mut f = f.clone(); Box::pin(async move { f(req).await }) }) } async fn get_hello(req: Request) -> Response { "hello".into_response() } fn make_router() -> Router { let mut router = atelier::router::Router::new(); macro_rules! r { ($m:expr, $p:expr, $h:expr) => { router.register($m.to_string(), $p.to_string(), make_handler($h)) }; } r!("GET", "/hello", get_hello); router } async fn serve( dbs: Dbs, router: Arc, req: axum::extract::Request, ) -> axum::response::Response { let method = req.method().as_str(); let uri = format!("{}", req.uri()); let (handler, pathParams) = match router.get(method, &uri) { Ok(h) => h, Err(sc) => { return (http::status::StatusCode::from_u16(sc).unwrap(), "") .into_response() }, }; handler(req).await } async fn go() -> Result<()> { let mut conn = rusqlite::Connection::open("./shelves.db")?; migrate(&mut conn)?; let (tx, _, _) = atelier::rusqlite_thread_pool::spawn_threadpool_supervised( 4, "./shelves.db", |conn| init(conn), )?; let addr = "127.0.0.1:8333".parse::()?; let listener = TcpListener::bind(addr).await?; let router = Arc::new(make_router()); let s = move |req: Request| { let tx = tx.clone(); let router = router.clone(); serve(tx, router.clone(), req) }; axum::serve(listener, s.into_make_service()).await?; Ok(()) } fn main() { let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap(); rt.block_on(go()).unwrap(); }