diff --git a/crates/api/src/lib.rs b/crates/api/src/lib.rs index 85b5404..e70fe54 100644 --- a/crates/api/src/lib.rs +++ b/crates/api/src/lib.rs @@ -1,48 +1,70 @@ use std::sync::Arc; use tower_http::trace::TraceLayer; use axum::{ routing::get, extract::{State, Request, Json, Path, Extension, Query}, routing::post, }; pub use axum::serve; struct AppState { collar: libcollar::State, } pub fn app(collar: libcollar::State) -> axum::Router { let state = Arc::new(AppState { collar }); // build our application with a single route let app = axum::Router::new() .route("/", get(|| async { "collared." })) .route("/ng/eiface/{name}", post(post_ng_eiface)) + .route("/store/namespace/{name}", post(post_ns)) .route("/store/namespace/{name}/{key}/{value}", post(post_ns_key)) .route("/store/namespace/{name}/{key}", get(get_ns_key)) .with_state(state) .layer(tower_http::trace::TraceLayer::new_for_http()); app } +async fn post_ns(State(state): State>, Path(name): Path) -> Result { + let ns = state.collar.store.namespaces(); + + // First, ensure the namespace exists + if let Err(e) = ns.define(&name) { + return Err(format!("Failed to define namespace '{}': {:?}", name, e)); + } + + Ok("ok".to_string()) +} + async fn post_ns_key(State(state): State>, Path((name, key, value)): Path<(String, String, String)>) -> Result { let ns = state.collar.store.namespaces(); - Ok("todo".to_string()) + + // Try to reserve the key-value pair + match ns.reserve(&name, &key, &value) { + Ok(_) => Ok(format!("Reserved key '{}' with value '{}' in namespace '{}'", key, value, name)), + Err(e) => Err(format!("Failed to reserve key '{}' in namespace '{}': {:?}", key, name, e)), + } } async fn get_ns_key(State(state): State>, Path((name, key)): Path<(String, String)>) -> Result { let ns = state.collar.store.namespaces(); - Ok("todo".to_string()) + + match ns.get(&name, &key) { + Ok(Some(value)) => Ok(value), + Ok(None) => Err(format!("Key '{}' not found in namespace '{}'", key, name)), + Err(e) => Err(format!("Failed to get key '{}' from namespace '{}': {:?}", key, name, e)), + } } async fn post_ng_eiface(State(state): State>, Path(name): Path) -> Result { let fname = name.clone(); let result = state.collar.leash().gated(move || { Ok(libcollar::ng::new_eiface(&name)) }).await; Ok(format!("sup {} => {:?}", &fname, result)) }