use wsb::prelude::*;
use axum::{
extract::{Query, State},
http::StatusCode,
Json,
};
use super::sessions::ErrorResponse;
use wsb::fleet::git::tree::SubmoduleTree;
use crate::web::notes;
use crate::web::state::WebState;
fn internal_err(e: anyhow::Error) -> (StatusCode, Json<ErrorResponse>) {
(
StatusCode::INTERNAL_SERVER_ERROR,
Json(ErrorResponse {
error: e.to_string(),
}),
)
}
#[derive(Deserialize)]
pub struct PathQuery {
pub path: Option<String>,
}
pub async fn list_path_notes(
State(state): State<WebState>,
Query(q): Query<PathQuery>,
) -> Result<Json<serde_json::Value>, (StatusCode, Json<ErrorResponse>)> {
let root = state.workspace_root.clone();
let notes = match q.path {
Some(ref path) => notes::list_path_notes(&root, path).map_err(internal_err)?,
None => notes::list_all_notes(&root).map_err(internal_err)?,
};
Ok(Json(serde_json::json!({ "notes": notes })))
}
#[derive(Deserialize)]
pub struct CreateNoteBody {
pub path: String,
}
pub async fn create_path_note(
State(state): State<WebState>,
Json(body): Json<CreateNoteBody>,
) -> Result<(StatusCode, Json<serde_json::Value>), (StatusCode, Json<ErrorResponse>)> {
if body.path.trim().is_empty() {
return Err((
StatusCode::UNPROCESSABLE_ENTITY,
Json(ErrorResponse {
error: "path must not be empty".to_string(),
}),
));
}
let root = state.workspace_root.clone();
let submodule_paths: Vec<String> = match SubmoduleTree::discover_allow_empty(&root) {
Ok(tree) => tree
.top_down()
.iter()
.map(|node| node.display_path.clone())
.collect(),
Err(e) => return Err(internal_err(e.into())),
};
let note =
notes::create_path_note(&root, &body.path, &submodule_paths).map_err(internal_err)?;
Ok((
StatusCode::CREATED,
Json(serde_json::json!({ "note": note })),
))
}