Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If8fe8b38c1d9c4fecd40ff71f88d2ae06a6a6964
79 lines
1.8 KiB
Rust
79 lines
1.8 KiB
Rust
use axum::{
|
|
Json,
|
|
extract::{Path, State},
|
|
};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use crate::{error::ApiError, state::AppState};
|
|
|
|
#[derive(Debug, Deserialize)]
|
|
pub struct CreateSavedSearchRequest {
|
|
pub name: String,
|
|
pub query: String,
|
|
pub sort_order: Option<String>,
|
|
}
|
|
|
|
#[derive(Debug, Serialize)]
|
|
pub struct SavedSearchResponse {
|
|
pub id: String,
|
|
pub name: String,
|
|
pub query: String,
|
|
pub sort_order: Option<String>,
|
|
pub created_at: chrono::DateTime<chrono::Utc>,
|
|
}
|
|
|
|
pub async fn create_saved_search(
|
|
State(state): State<AppState>,
|
|
Json(req): Json<CreateSavedSearchRequest>,
|
|
) -> Result<Json<SavedSearchResponse>, ApiError> {
|
|
let id = uuid::Uuid::now_v7();
|
|
state
|
|
.storage
|
|
.save_search(id, &req.name, &req.query, req.sort_order.as_deref())
|
|
.await
|
|
.map_err(ApiError)?;
|
|
|
|
Ok(Json(SavedSearchResponse {
|
|
id: id.to_string(),
|
|
name: req.name,
|
|
query: req.query,
|
|
sort_order: req.sort_order,
|
|
created_at: chrono::Utc::now(),
|
|
}))
|
|
}
|
|
|
|
pub async fn list_saved_searches(
|
|
State(state): State<AppState>,
|
|
) -> Result<Json<Vec<SavedSearchResponse>>, ApiError> {
|
|
let searches = state
|
|
.storage
|
|
.list_saved_searches()
|
|
.await
|
|
.map_err(ApiError)?;
|
|
Ok(Json(
|
|
searches
|
|
.into_iter()
|
|
.map(|s| {
|
|
SavedSearchResponse {
|
|
id: s.id.to_string(),
|
|
name: s.name,
|
|
query: s.query,
|
|
sort_order: s.sort_order,
|
|
created_at: s.created_at,
|
|
}
|
|
})
|
|
.collect(),
|
|
))
|
|
}
|
|
|
|
pub async fn delete_saved_search(
|
|
State(state): State<AppState>,
|
|
Path(id): Path<uuid::Uuid>,
|
|
) -> Result<Json<serde_json::Value>, ApiError> {
|
|
state
|
|
.storage
|
|
.delete_saved_search(id)
|
|
.await
|
|
.map_err(ApiError)?;
|
|
Ok(Json(serde_json::json!({ "deleted": true })))
|
|
}
|