From 9ba9c3c5672f4b0ebd63d47976371698e1381d72 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 9 Mar 2026 23:11:05 -0700 Subject: [PATCH] Add a single route at /race That returns the complete race state, which, for now, is only the name of the race. New rust features seen for the first time as of this commit: * std::sync::Arc for atomically-reference-counted pointers (with thread-safe reference counting as you would expect from the name). * "crate::" in 'use' paths to reference the root of the current project * impl: For creating functions associated with a struct * Destructuring in a function parameter: State(state): State> * clone() to carefully give the RaceResponse a string it owns. (Note: The rust compiler wouldn't even accept the code without this clone(): "cannot move out of an `Arc`) --- src/handlers.rs | 17 +++++++++++++++++ src/main.rs | 11 ++++++++++- src/state.rs | 15 +++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 src/handlers.rs create mode 100644 src/state.rs diff --git a/src/handlers.rs b/src/handlers.rs new file mode 100644 index 0000000..3586d64 --- /dev/null +++ b/src/handlers.rs @@ -0,0 +1,17 @@ +use axum::Json; +use axum::extract::State; +use serde::Serialize; +use std::sync::Arc; + +use crate::state::AppState; + +#[derive(Serialize)] +pub struct RaceResponse { + pub name: String, +} + +pub async fn get_race(State(state): State>) -> Json { + Json(RaceResponse { + name: state.race_name.clone(), + }) +} diff --git a/src/main.rs b/src/main.rs index baca8fe..ecb0dcd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,9 @@ mod config; +mod handlers; +mod state; +use axum::Router; +use axum::routing::get; use std::error::Error; #[tokio::main] @@ -17,12 +21,17 @@ async fn main() -> Result<(), Box> { eprintln!("Race: {}", config.name); + let state = state::AppState::new(config); + + // Public read routes + let read_routes = Router::new().route("/race", get(handlers::get_race)); + let bind = "0.0.0.0:3000"; eprintln!("Listening on {}", bind); let listener = tokio::net::TcpListener::bind(&bind).await?; - let app = axum::Router::new(); + let app = Router::new().merge(read_routes).with_state(state); axum::serve(listener, app) .with_graceful_shutdown(async move { diff --git a/src/state.rs b/src/state.rs new file mode 100644 index 0000000..0efa810 --- /dev/null +++ b/src/state.rs @@ -0,0 +1,15 @@ +use std::sync::Arc; + +use crate::config::ConfigFile; + +pub struct AppState { + pub race_name: String, +} + +impl AppState { + pub fn new(config: ConfigFile) -> Arc { + Arc::new(Self { + race_name: config.name, + }) + } +} -- 2.45.2