use axum::extract::FromRef; use axum::extract::State; use axum::routing::get; use axum::Router; use std::sync::Arc; use tokio::sync::RwLock; use std::fmt::Debug; // Simple state #[derive(Clone, Debug)] pub struct AppState { substate1: SubState1, } #[derive(Clone, Debug)] pub struct SubState1 { mutcounter: Arc<RwLock<MutCounter>>, } #[derive(Clone, Debug)] pub struct MutCounter { counter: u32, } impl MutCounter { pub fn inc(&mut self) { self.counter += 1; } pub fn new() -> Self { MutCounter { counter: 3 } } } impl FromRef<AppState> for SubState1 { fn from_ref(app_state: &AppState) -> SubState1 { app_state.substate1.clone() } } // End simple state // Generic state // #[derive(Clone, Debug)] pub struct GenAppState<GSS: Clone + GenMutCounter> { substate1: GenSubState1<GSS> } #[derive(Clone, Debug)] pub struct GenSubState1<GSS: Clone + GenMutCounter> { mutcounter: Arc<RwLock<GSS>> } impl <GSS: Clone + GenMutCounter> FromRef<GenAppState<GSS>> for GenSubState1<GSS> { fn from_ref(app_state: &GenAppState<GSS>) -> GenSubState1<GSS> { app_state.substate1.clone() } } pub trait GenMutCounter { fn inc(&mut self); } // End generic state #[derive(Clone, Debug)] pub struct GenMutCounterU32 { counter: u32 } impl GenMutCounterU32 { pub fn new() -> Self { GenMutCounterU32 { counter: 4 } } } impl GenMutCounter for GenMutCounterU32 { fn inc(&mut self) { self.counter += 1; } } #[tokio::main] async fn main() { let listener = tokio::net::TcpListener::bind("127.0.0.1:3000") .await .unwrap(); axum::serve(listener, app()).await.unwrap(); println!("Hello, world!"); } fn app() -> Router { let state = AppState { substate1: SubState1 { mutcounter: Arc::new(RwLock::new(MutCounter::new())), }, }; let state2 = GenAppState { substate1: GenSubState1 { mutcounter: Arc::new(RwLock::new(GenMutCounterU32::new())) } }; let app = Router::new() .route("/", get(root3)) .with_state(state2.clone()); app } pub async fn root(State(app_state): State<AppState>) -> &'static str { dbg!(&app_state); let mut a = app_state.substate1.mutcounter.write().await; a.inc(); "AAAAAAAAAAAAAAAAA" } pub async fn root2(State(sub_state1): State<SubState1>) -> &'static str { dbg!(&sub_state1); let mut a = sub_state1.mutcounter.write().await; a.inc(); "AAAAAAAAAAAAAAAAA" } pub async fn root3<GMC>(State(gen_sub_state1): State<GenSubState1<GMC>>) -> &'static str where GMC: GenMutCounter + Clone + Debug { dbg!(&gen_sub_state1); let mut a = gen_sub_state1.mutcounter.write().await; a.inc(); "AAAAAAAAAAAAAAAAA" } #[cfg(test)] mod tests { use super::*; use axum::body::Body; use axum::http::{Request, StatusCode}; use tower::{Service, ServiceExt}; #[tokio::test] async fn hw_test() { let app = app(); for _ in 0..3 { let response = app .clone() .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap()) .await .unwrap(); assert_eq!(response.status(), StatusCode::OK); } } }