Skip to main content

csi_webserver_core/routes/
mod.rs

1//! HTTP route handler modules.
2
3pub mod config;
4pub mod control;
5pub mod devices;
6pub mod info;
7pub mod ws;
8
9use std::sync::Arc;
10
11use axum::{
12    Json,
13    extract::{FromRequestParts, Path},
14    http::{StatusCode, request::Parts},
15};
16
17use crate::{
18    models::ApiResponse,
19    state::{AppState, DeviceHandle},
20};
21
22/// Extractor that resolves the `{id}` path segment to a [`DeviceHandle`] from
23/// the registry. Rejects with `404 Not Found` when no such device exists, so
24/// every per-device handler shares one lookup-and-reject path.
25pub struct Device(pub Arc<DeviceHandle>);
26
27impl FromRequestParts<AppState> for Device {
28    type Rejection = (StatusCode, Json<ApiResponse>);
29
30    async fn from_request_parts(
31        parts: &mut Parts,
32        state: &AppState,
33    ) -> Result<Self, Self::Rejection> {
34        let Path(id) = Path::<String>::from_request_parts(parts, state)
35            .await
36            .map_err(|_| {
37                (
38                    StatusCode::BAD_REQUEST,
39                    Json(ApiResponse {
40                        success: false,
41                        message: "Missing device id in request path".to_string(),
42                    }),
43                )
44            })?;
45
46        state.devices.get(&id).map(Device).ok_or_else(|| {
47            (
48                StatusCode::NOT_FOUND,
49                Json(ApiResponse {
50                    success: false,
51                    message: format!("No device with id '{id}'"),
52                }),
53            )
54        })
55    }
56}