Add local KV store commands

This commit is contained in:
Eric Wendland 2026-05-16 21:52:35 +02:00
commit 1a0f1e7671
14 changed files with 395 additions and 13 deletions

View file

@ -7,4 +7,5 @@ license.workspace = true
[dependencies]
serde.workspace = true
thiserror.workspace = true
geth-types = { path = "../geth-types" }

View file

@ -6,9 +6,66 @@ pub struct KvResource {
pub id: KvId,
pub resource: ResourceId,
pub name: String,
pub sync_status: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct KvEntry {
pub store: KvId,
pub key: String,
pub value: String,
}
#[derive(Debug, thiserror::Error)]
pub enum KvError {
#[error("invalid kv store name: {0}")]
InvalidName(String),
#[error("invalid kv key: {0}")]
InvalidKey(String),
}
pub fn validate_kv_name(name: &str) -> Result<(), KvError> {
if name.is_empty()
|| !name
.bytes()
.all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b'.' | b'_' | b'-'))
{
return Err(KvError::InvalidName(name.to_owned()));
}
Ok(())
}
pub fn validate_kv_key(key: &str) -> Result<(), KvError> {
if key.is_empty() || key.bytes().any(|byte| byte == 0 || byte == b'\n') {
return Err(KvError::InvalidKey(key.to_owned()));
}
Ok(())
}
#[must_use]
pub fn iroh_docs_roadmap() -> &'static str {
"future kv storage uses Iroh Documents namespaces with prefix-scoped authorization"
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn kv_name_validation_rejects_paths_and_empty_names() {
assert!(validate_kv_name("prefs").is_ok());
assert!(validate_kv_name("apps.foo").is_ok());
assert!(validate_kv_name("").is_err());
assert!(validate_kv_name("../prefs").is_err());
assert!(validate_kv_name("prefs/main").is_err());
assert!(validate_kv_name("prefs main").is_err());
}
#[test]
fn kv_key_validation_rejects_empty_newline_and_nul() {
assert!(validate_kv_key("apps/foo/theme").is_ok());
assert!(validate_kv_key("").is_err());
assert!(validate_kv_key("apps/foo\nbar").is_err());
assert!(validate_kv_key("apps/foo\0bar").is_err());
}
}