134 lines
3.4 KiB
Rust
134 lines
3.4 KiB
Rust
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::limit_zone::{
|
|
CreateLimitZoneParams, LimitZoneService, UpdateLimitZoneParams,
|
|
};
|
|
use crate::service::proxy::types::LimitZoneConfig;
|
|
|
|
#[derive(Serialize)]
|
|
pub(crate) struct LimitZoneResponse {
|
|
pub id: Uuid,
|
|
pub name: String,
|
|
pub key: String,
|
|
pub rate: String,
|
|
pub override_of_id: Option<Uuid>,
|
|
}
|
|
|
|
impl From<LimitZoneConfig> for LimitZoneResponse {
|
|
fn from(c: LimitZoneConfig) -> Self {
|
|
Self {
|
|
id: c.id,
|
|
name: c.name,
|
|
key: c.key,
|
|
rate: c.rate,
|
|
override_of_id: c.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct CreateLimitZoneRequest {
|
|
pub name: String,
|
|
pub key: String,
|
|
pub rate: String,
|
|
pub override_of_id: Option<Uuid>,
|
|
}
|
|
|
|
impl From<CreateLimitZoneRequest> for CreateLimitZoneParams {
|
|
fn from(r: CreateLimitZoneRequest) -> Self {
|
|
Self {
|
|
name: r.name,
|
|
key: r.key,
|
|
rate: r.rate,
|
|
override_of_id: r.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize)]
|
|
pub(crate) struct UpdateLimitZoneRequest {
|
|
pub name: Option<String>,
|
|
pub key: Option<String>,
|
|
pub rate: Option<String>,
|
|
pub override_of_id: Option<Option<Uuid>>,
|
|
}
|
|
|
|
impl From<UpdateLimitZoneRequest> for UpdateLimitZoneParams {
|
|
fn from(r: UpdateLimitZoneRequest) -> Self {
|
|
Self {
|
|
name: r.name,
|
|
key: r.key,
|
|
rate: r.rate,
|
|
override_of_id: r.override_of_id,
|
|
}
|
|
}
|
|
}
|
|
|
|
async fn list_limit_zones(
|
|
State(svc): State<Arc<dyn LimitZoneService>>,
|
|
) -> Result<Json<Vec<LimitZoneResponse>>, AppError> {
|
|
let zones = svc.list().await?;
|
|
Ok(Json(zones.into_iter().map(Into::into).collect()))
|
|
}
|
|
|
|
async fn create_limit_zone(
|
|
State(svc): State<Arc<dyn LimitZoneService>>,
|
|
Json(body): Json<CreateLimitZoneRequest>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
let zone = svc.create(body.into()).await?;
|
|
Ok((StatusCode::CREATED, Json(LimitZoneResponse::from(zone))))
|
|
}
|
|
|
|
async fn get_limit_zone(
|
|
State(svc): State<Arc<dyn LimitZoneService>>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<Json<LimitZoneResponse>, AppError> {
|
|
let zone = svc.get(id).await?;
|
|
Ok(Json(zone.into()))
|
|
}
|
|
|
|
async fn update_limit_zone(
|
|
State(svc): State<Arc<dyn LimitZoneService>>,
|
|
Path(id): Path<Uuid>,
|
|
Json(body): Json<UpdateLimitZoneRequest>,
|
|
) -> Result<Json<LimitZoneResponse>, AppError> {
|
|
let zone = svc.update(id, body.into()).await?;
|
|
Ok(Json(zone.into()))
|
|
}
|
|
|
|
async fn delete_limit_zone(
|
|
State(svc): State<Arc<dyn LimitZoneService>>,
|
|
Path(id): Path<Uuid>,
|
|
) -> Result<impl IntoResponse, AppError> {
|
|
let deleted = svc.delete(id).await?;
|
|
if deleted {
|
|
Ok((StatusCode::NO_CONTENT,))
|
|
} else {
|
|
Err(AppError::NotFound)
|
|
}
|
|
}
|
|
|
|
pub(super) fn routes() -> ApiRouter {
|
|
ApiRouter::new()
|
|
.route(
|
|
"/limit-zones",
|
|
axum::routing::get(list_limit_zones).post(create_limit_zone),
|
|
)
|
|
.route(
|
|
"/limit-zones/{id}",
|
|
axum::routing::get(get_limit_zone)
|
|
.put(update_limit_zone)
|
|
.delete(delete_limit_zone),
|
|
)
|
|
}
|