use axum::{ Json, Router, extract::{Query, State}, http::StatusCode, response::IntoResponse, routing::{get, post}, }; pub use fil_core::{KastenHandle, Tag, Zettel}; use serde::Deserialize; use tracing::instrument; use super::error::ApiError; pub fn router() -> Router { Router::new() .route("/", get(list_zettels)) .route("/", post(create_zettel)) .route("/search", get(search_zettels)) // .route("/{id}/toggle", post(toggle_task_completion)) } #[axum::debug_handler] #[instrument(skip(kh))] async fn list_zettels( axum::extract::State(kh): State, ) -> Result { let kt = kh.read().await; let all_zettels = kt.fetch_all_zettels().await?; drop(kt); Ok(Json(all_zettels)) } #[axum::debug_handler] #[instrument(skip(kh))] async fn create_zettel( State(kh): State, Json(params): Json, ) -> Result { let mut kt = kh.write().await; let zettel = Zettel::new(params.title, &mut kt, params.tags).await?; drop(kt); Ok(Json(zettel)) } #[axum::debug_handler] #[instrument(skip(kh))] #[expect(unreachable_code)] async fn search_zettels( State(kh): State, Query(params): Query, ) -> Result { let kt = kh.read().await; // let _ = (kt, params); drop(kt); todo!("dispatch on params.scope once search is implemented"); Ok(StatusCode::OK) } #[derive(Deserialize, Debug)] struct ZettelCreationParams { title: String, tags: Vec, } #[derive(Deserialize, Debug, Default, Clone, Copy)] #[serde(rename_all = "snake_case")] enum SearchScope { // honestly wont be doing all these just yet but its ok Name, Content, Tags, #[default] All, } #[derive(Deserialize, Debug)] #[expect(dead_code)] struct SearchParams { q: String, #[serde(default)] scope: SearchScope, } // what would we need from zettels