1use async_trait::async_trait;
8
9use crate::PathError;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
21pub enum MemoryLevel {
22 L0,
23 L1,
24 L2,
27 L3,
28 L4,
29}
30
31impl MemoryLevel {
32 pub fn dir_name(self) -> &'static str {
34 match self {
35 Self::L0 => "L0",
36 Self::L1 => "L1",
37 Self::L2 => "L2",
38 Self::L3 => "L3",
39 Self::L4 => "L4",
40 }
41 }
42}
43
44#[derive(Debug, thiserror::Error)]
46pub enum MemoryError {
47 #[error("patch failed: {0}")]
48 Patch(#[from] PatchError),
49 #[error("validation failed at level {level:?}: {reason}")]
50 ValidationFailed { level: MemoryLevel, reason: String },
51 #[error("not found: {0}")]
52 NotFound(String),
53 #[error("path denied: {0}")]
54 PathDenied(String),
55 #[error("io: {0}")]
56 Io(#[from] std::io::Error),
57}
58
59#[derive(Debug, Clone, thiserror::Error)]
63pub enum PatchError {
64 #[error("patch not found: old_content absent")]
65 NotFound,
66 #[error("patch not unique: found {count} matches, expected 1")]
67 NotUnique { count: usize },
68}
69
70impl From<PathError> for MemoryError {
71 fn from(err: PathError) -> Self {
72 match err {
73 PathError::Io(e) => Self::Io(e),
74 other => Self::PathDenied(other.to_string()),
75 }
76 }
77}
78
79#[async_trait]
81pub trait MemoryStore: Send + Sync {
82 async fn read(&self, path: &str) -> Result<String, MemoryError>;
84 async fn write(&self, path: &str, content: &str) -> Result<(), MemoryError>;
86 async fn patch(&self, path: &str, old: &str, new: &str) -> Result<(), MemoryError>;
88 async fn delete(&self, path: &str) -> Result<(), MemoryError>;
90 async fn list(&self, level: MemoryLevel) -> Result<Vec<String>, MemoryError>;
92 fn validate(&self, level: MemoryLevel, content: &str) -> Result<(), MemoryError>;
94 async fn read_root(&self, name: &str) -> Result<String, MemoryError>;
96}
97
98#[derive(Debug, Default, Clone)]
100pub struct NullMemoryStore;
101
102#[async_trait]
103impl MemoryStore for NullMemoryStore {
104 async fn read(&self, path: &str) -> Result<String, MemoryError> {
105 Err(MemoryError::NotFound(path.to_string()))
106 }
107
108 async fn write(&self, _path: &str, _content: &str) -> Result<(), MemoryError> {
109 Ok(())
110 }
111
112 async fn patch(&self, path: &str, _old: &str, _new: &str) -> Result<(), MemoryError> {
113 Err(MemoryError::NotFound(path.to_string()))
114 }
115
116 async fn delete(&self, _path: &str) -> Result<(), MemoryError> {
117 Ok(())
118 }
119
120 async fn list(&self, _level: MemoryLevel) -> Result<Vec<String>, MemoryError> {
121 Ok(Vec::new())
122 }
123
124 fn validate(&self, _level: MemoryLevel, _content: &str) -> Result<(), MemoryError> {
125 Ok(())
126 }
127
128 async fn read_root(&self, name: &str) -> Result<String, MemoryError> {
129 Err(MemoryError::NotFound(name.to_string()))
130 }
131}