78 lines
2.1 KiB
Rust
78 lines
2.1 KiB
Rust
use geth_types::{KvId, ResourceId};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
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(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
|
pub struct KvSyncEntry {
|
|
pub key: String,
|
|
pub value: String,
|
|
pub updated_at_ms: i64,
|
|
}
|
|
|
|
#[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());
|
|
}
|
|
}
|