use car_secrets::{SecretError, SecretRef, SecretStatus, SecretStore, DEFAULT_SERVICE};
use serde_json::{json, Value};
fn make_ref(service: Option<&str>, key: &str) -> SecretRef {
SecretRef::new(service.unwrap_or(DEFAULT_SERVICE), key)
}
fn code_for(e: &SecretError) -> &'static str {
match e {
SecretError::NotFound { .. } => "not_found",
SecretError::Unavailable(_) => "unavailable",
SecretError::Backend(_) => "backend",
SecretError::InvalidJson(_) => "invalid_json",
}
}
fn json_err(e: SecretError) -> String {
let mut body = json!({
"code": code_for(&e),
"message": e.to_string(),
});
if let SecretError::NotFound { service, key } = &e {
body["context"] = json!({"service": service, "key": key});
}
body.to_string()
}
pub fn put(service: Option<&str>, key: &str, value: &str) -> Result<Value, String> {
let store = SecretStore::new();
store
.put(&make_ref(service, key), value)
.map_err(json_err)?;
Ok(json!({"service": service.unwrap_or(DEFAULT_SERVICE), "key": key, "stored": true}))
}
pub fn get(service: Option<&str>, key: &str) -> Result<Value, String> {
let store = SecretStore::new();
let v = store.get(&make_ref(service, key)).map_err(json_err)?;
Ok(json!({"service": service.unwrap_or(DEFAULT_SERVICE), "key": key, "value": v}))
}
pub fn delete(service: Option<&str>, key: &str) -> Result<Value, String> {
let store = SecretStore::new();
store
.delete(&make_ref(service, key))
.map_err(json_err)?;
Ok(json!({"service": service.unwrap_or(DEFAULT_SERVICE), "key": key, "deleted": true}))
}
pub fn status(service: Option<&str>, key: &str) -> Result<Value, String> {
let store = SecretStore::new();
let st: SecretStatus = store.status(&make_ref(service, key)).map_err(json_err)?;
serde_json::to_value(&st).map_err(|e| json!({"code": "backend", "message": e.to_string()}).to_string())
}
pub fn is_available() -> Value {
let check = SecretStore::new().availability();
serde_json::to_value(&check).unwrap_or_else(|_| json!({"available": check.available}))
}
pub fn read_raw(service: Option<&str>, key: &str) -> Result<String, String> {
SecretStore::new()
.get(&make_ref(service, key))
.map_err(json_err)
}