Something went wrong. Try again.
Something went wrong. Try again.
2.3 kB · 88 lines
Rust
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889use axum::{ Json, Router, extract::State, http::{ StatusCode, header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE}, }, routing::{get, post},};use color_eyre::eyre;use serde::{Deserialize, Serialize};use tower::ServiceBuilder;use tower_http::{ cors::{Any, CorsLayer}, services::ServeDir, trace::TraceLayer,};use tracing::{error, warn};
use crate::{AppState, config::Config, device_storage::Mode};
pub async fn app(state: AppState, config: &Config) -> eyre::Result<Router> { let app = Router::new() .route("/api/health", get(health_check)) .route("/api/devices", get(get_devices)) .route("/api/device", post(update_device)) .with_state(state) .fallback_service(ServeDir::new(&config.static_files_dir)) .layer( ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .layer( CorsLayer::new() .allow_headers([AUTHORIZATION, CONTENT_TYPE, ACCEPT]) .allow_origin(Any) .allow_methods(Any), ), );
Ok(app)}
#[derive(Debug, Clone, Serialize, Deserialize)]pub struct Device { pub id: String, pub mode: Mode, pub color: String, pub sun_brightness: u8,}
async fn get_devices(state: State<AppState>) -> Json<Vec<Device>> { let devices = state .device_storage .get_all() .await .iter() .map(|(id, data)| Device { id: id.clone(), mode: data.mode.clone(), color: data.color.clone(), sun_brightness: data.sun_brightness, }) .collect();
Json(devices)}
async fn update_device(state: State<AppState>, Json(device): Json<Device>) -> StatusCode { if let Err(err) = state .device_storage .update_state(&device.id, device.mode, device.color, device.sun_brightness) .await { warn!("Failed to update device: {}", err); return StatusCode::BAD_REQUEST; }
if let Err(err) = state.device_change_events.send(device.id) { error!("Failed to send device change event: {}", err); return StatusCode::INTERNAL_SERVER_ERROR; }
StatusCode::OK}
async fn health_check() -> &'static str { "ok"}