use axum::Router; use axum::routing::get; use axum::serve::Listener as AxumListener; use crate::db::{Database, DatabaseInterface}; use crate::listener::{Listener, ListenerKind}; use crate::stream::{AbstractSocketAddr, AbstractStreamKind}; impl AxumListener for Listener { type Io = AbstractStreamKind; type Addr = AbstractSocketAddr; async fn accept(&mut self) -> (Self::Io, Self::Addr) { loop { let res = match &self.kind { ListenerKind::Tcp(l) => l .accept() .await .map(|(stream, remote_addr)| (stream.into(), remote_addr.into())), ListenerKind::Uds(l) => l .accept() .await .map(|(stream, remote_addr)| (stream.into(), remote_addr.into())), }; match res { Ok((stream, remote_addr)) => return (stream, remote_addr), Err(e) => { // Here the error could be fatal, or could simply be that a client aborted the connected, // in which case we don't want to crash the server, simply skip this client connection. // https://doc.rust-lang.org/stable/std/net/struct.TcpListener.html#errors match e.kind() { std::io::ErrorKind::ConnectionAborted => {} _ => panic!("Unrecoverable HTTP client connection error: {e}"), } } } } } fn local_addr(&self) -> std::io::Result { match &self.kind { ListenerKind::Tcp(l) => l.local_addr().map(Into::into), ListenerKind::Uds(l) => l.local_addr().map(Into::into), } } } pub async fn http_listen(listener: Listener, db: Database) { let app = Router::new().route("/", get(handler)).with_state(db); axum::serve(listener, app).await.unwrap(); } pub async fn handler() -> &'static str { "hello world" }