use std::sync::Arc; use axum::{ Json, extract::{Path, State}, http::StatusCode, response::IntoResponse, }; use serde::{Deserialize, Serialize}; use uuid::Uuid; use crate::routes::api::{ApiRouter, AppError}; use crate::service::proxy::cache_zone::{ CacheZoneService, CreateCacheZoneParams, UpdateCacheZoneParams, }; use crate::service::proxy::types::CacheZoneConfig; #[derive(Serialize)] pub(crate) struct CacheZoneResponse { pub id: Uuid, pub name: String, pub path: String, pub size: String, pub override_of_id: Option, } impl From for CacheZoneResponse { fn from(c: CacheZoneConfig) -> Self { Self { id: c.id, name: c.name, path: c.path, size: c.size, override_of_id: c.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct CreateCacheZoneRequest { pub name: String, pub path: String, pub size_limit: String, pub override_of_id: Option, } impl From for CreateCacheZoneParams { fn from(r: CreateCacheZoneRequest) -> Self { Self { name: r.name, path: r.path, size_limit: r.size_limit, override_of_id: r.override_of_id, } } } #[derive(Deserialize)] pub(crate) struct UpdateCacheZoneRequest { pub name: Option, pub path: Option, pub size_limit: Option, pub override_of_id: Option>, } impl From for UpdateCacheZoneParams { fn from(r: UpdateCacheZoneRequest) -> Self { Self { name: r.name, path: r.path, size_limit: r.size_limit, override_of_id: r.override_of_id, } } } async fn list_cache_zones( State(svc): State>, ) -> Result>, AppError> { let zones = svc.list().await?; Ok(Json(zones.into_iter().map(Into::into).collect())) } async fn create_cache_zone( State(svc): State>, Json(body): Json, ) -> Result { let zone = svc.create(body.into()).await?; Ok((StatusCode::CREATED, Json(CacheZoneResponse::from(zone)))) } async fn get_cache_zone( State(svc): State>, Path(id): Path, ) -> Result, AppError> { let zone = svc.get(id).await?; Ok(Json(zone.into())) } async fn update_cache_zone( State(svc): State>, Path(id): Path, Json(body): Json, ) -> Result, AppError> { let zone = svc.update(id, body.into()).await?; Ok(Json(zone.into())) } async fn delete_cache_zone( State(svc): State>, Path(id): Path, ) -> Result { let deleted = svc.delete(id).await?; if deleted { Ok((StatusCode::NO_CONTENT,)) } else { Err(AppError::NotFound) } } pub(super) fn routes() -> ApiRouter { ApiRouter::new() .route( "/cache-zones", axum::routing::get(list_cache_zones).post(create_cache_zone), ) .route( "/cache-zones/{id}", axum::routing::get(get_cache_zone) .put(update_cache_zone) .delete(delete_cache_zone), ) }