use std::net::SocketAddr; 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 Box>>; type Router = atelier::router::Router; fn make_handler(f: F) -> Handler where Fut: Future, F: FnMut(Request) -> Fut + Clone + 'static, { Box::new(move |req| { let mut f = f.clone(); Box::new(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, $p, make_handler($h)) }; } r!("get", "/hello", get_hello); router } async fn serve( dbs: Dbs, router: &Router, req: axum::extract::Request, ) -> axum::response::Response { let method = req.method().as_str(); let uri = format!("{}", req.uri()); let handler = match router.get(method, uri) { (Some(h), _) => h, (None, Some(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 = make_router(); let serve = move |req| { let tx = tx.clone(); serve(tx, router, req) }; axum::serve(listener, serve.into_make_service()).await?; Ok(()) } fn main() { let rt = tokio::runtime::Builder::new_multi_thread() .enable_all() .build() .unwrap(); rt.block_on(go()).unwrap(); }