use axum::{Router, extract::State, response::IntoResponse, routing::get}; use maud::html; use tokio::net::TcpListener; mod contact; use contact::Contact; #[derive(Clone)] struct AppState { contacts: Vec, } #[axum::debug_handler] async fn contacts( // access the state via the `State` extractor // extracting a state of the wrong type results in a compile error State(state): State, ) -> impl IntoResponse { html! { ul { @for contact in &state.contacts { li { (&contact.name) } } } } } #[tokio::main] async fn main() -> Result<(), anyhow::Error> { let state = AppState { contacts: vec![ Contact { name: "Foo Bar".to_string(), }, Contact { name: "Baz Qux".to_string(), }, ], }; let app = Router::new() .route("/", get(|| async { "Hello, World!" })) .route("/contacts", get(contacts)) .with_state(state); let mut listenfd = listenfd::ListenFd::from_env(); let listener = match listenfd.take_tcp_listener(0)? { Some(listener) => { listener.set_nonblocking(true)?; TcpListener::from_std(listener) } None => TcpListener::bind("0.0.0.0:3000").await, }?; axum::serve(listener, app).await.unwrap(); Ok(()) }