2026-02-16 16:24:21 +00:00
|
|
|
use crate::http::context::{AppContext, OpenApiResult, bad_request};
|
|
|
|
|
use crate::io::fs;
|
2026-02-16 16:50:50 +00:00
|
|
|
use poem_openapi::{Object, OpenApi, Tags, payload::Json};
|
2026-02-16 16:35:25 +00:00
|
|
|
use serde::Deserialize;
|
|
|
|
|
use std::sync::Arc;
|
2026-02-16 16:24:21 +00:00
|
|
|
|
2026-02-16 16:50:50 +00:00
|
|
|
#[derive(Tags)]
|
|
|
|
|
enum ProjectTags {
|
|
|
|
|
Project,
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:35:25 +00:00
|
|
|
#[derive(Deserialize, Object)]
|
|
|
|
|
struct PathPayload {
|
|
|
|
|
path: String,
|
2026-02-16 16:24:21 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:35:25 +00:00
|
|
|
pub struct ProjectApi {
|
|
|
|
|
pub ctx: Arc<AppContext>,
|
2026-02-16 16:24:21 +00:00
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:50:50 +00:00
|
|
|
#[OpenApi(tag = "ProjectTags::Project")]
|
2026-02-16 16:35:25 +00:00
|
|
|
impl ProjectApi {
|
2026-02-16 16:50:50 +00:00
|
|
|
/// Get the currently open project path (if any).
|
|
|
|
|
///
|
|
|
|
|
/// Returns null when no project is open.
|
2026-02-16 16:35:25 +00:00
|
|
|
#[oai(path = "/project", method = "get")]
|
|
|
|
|
async fn get_current_project(&self) -> OpenApiResult<Json<Option<String>>> {
|
|
|
|
|
let result = fs::get_current_project(&self.ctx.state, self.ctx.store.as_ref())
|
|
|
|
|
.map_err(bad_request)?;
|
|
|
|
|
Ok(Json(result))
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:50:50 +00:00
|
|
|
/// Open a project and set it as the current project.
|
|
|
|
|
///
|
|
|
|
|
/// Persists the selected path for later sessions.
|
2026-02-16 16:35:25 +00:00
|
|
|
#[oai(path = "/project", method = "post")]
|
|
|
|
|
async fn open_project(&self, payload: Json<PathPayload>) -> OpenApiResult<Json<String>> {
|
|
|
|
|
let confirmed = fs::open_project(payload.0.path, &self.ctx.state, self.ctx.store.as_ref())
|
|
|
|
|
.await
|
|
|
|
|
.map_err(bad_request)?;
|
|
|
|
|
Ok(Json(confirmed))
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-16 16:50:50 +00:00
|
|
|
/// Close the current project and clear the stored selection.
|
2026-02-16 16:35:25 +00:00
|
|
|
#[oai(path = "/project", method = "delete")]
|
|
|
|
|
async fn close_project(&self) -> OpenApiResult<Json<bool>> {
|
|
|
|
|
fs::close_project(&self.ctx.state, self.ctx.store.as_ref()).map_err(bad_request)?;
|
|
|
|
|
Ok(Json(true))
|
|
|
|
|
}
|
2026-02-16 18:57:39 +00:00
|
|
|
|
|
|
|
|
/// List known projects from the store.
|
|
|
|
|
#[oai(path = "/projects", method = "get")]
|
|
|
|
|
async fn list_known_projects(&self) -> OpenApiResult<Json<Vec<String>>> {
|
|
|
|
|
let projects = fs::get_known_projects(self.ctx.store.as_ref()).map_err(bad_request)?;
|
|
|
|
|
Ok(Json(projects))
|
|
|
|
|
}
|
2026-02-16 19:53:31 +00:00
|
|
|
|
|
|
|
|
/// Forget a known project path.
|
|
|
|
|
#[oai(path = "/projects/forget", method = "post")]
|
|
|
|
|
async fn forget_known_project(&self, payload: Json<PathPayload>) -> OpenApiResult<Json<bool>> {
|
|
|
|
|
fs::forget_known_project(payload.0.path, self.ctx.store.as_ref()).map_err(bad_request)?;
|
|
|
|
|
Ok(Json(true))
|
|
|
|
|
}
|
2026-02-16 16:24:21 +00:00
|
|
|
}
|