walrus_daemon/hook/system/memory/
storage.rs1use anyhow::Result;
7use std::{
8 collections::HashMap,
9 path::{Path, PathBuf},
10 sync::RwLock,
11};
12
13pub trait Storage: Send + Sync {
15 fn read(&self, path: &Path) -> Result<String>;
16 fn write(&self, path: &Path, content: &str) -> Result<()>;
17 fn delete(&self, path: &Path) -> Result<()>;
18 fn list(&self, dir: &Path) -> Result<Vec<PathBuf>>;
19 fn create_dir_all(&self, path: &Path) -> Result<()>;
20 fn exists(&self, path: &Path) -> bool;
21 fn rename(&self, from: &Path, to: &Path) -> Result<()>;
22}
23
24pub struct FsStorage;
26
27impl Storage for FsStorage {
28 fn read(&self, path: &Path) -> Result<String> {
29 Ok(std::fs::read_to_string(path)?)
30 }
31
32 fn write(&self, path: &Path, content: &str) -> Result<()> {
33 Ok(std::fs::write(path, content)?)
34 }
35
36 fn delete(&self, path: &Path) -> Result<()> {
37 Ok(std::fs::remove_file(path)?)
38 }
39
40 fn list(&self, dir: &Path) -> Result<Vec<PathBuf>> {
41 let mut paths = Vec::new();
42 for entry in std::fs::read_dir(dir)? {
43 paths.push(entry?.path());
44 }
45 Ok(paths)
46 }
47
48 fn create_dir_all(&self, path: &Path) -> Result<()> {
49 Ok(std::fs::create_dir_all(path)?)
50 }
51
52 fn exists(&self, path: &Path) -> bool {
53 path.exists()
54 }
55
56 fn rename(&self, from: &Path, to: &Path) -> Result<()> {
57 Ok(std::fs::rename(from, to)?)
58 }
59}
60
61pub struct MemStorage {
63 files: RwLock<HashMap<PathBuf, String>>,
64}
65
66impl Default for MemStorage {
67 fn default() -> Self {
68 Self {
69 files: RwLock::new(HashMap::new()),
70 }
71 }
72}
73
74impl MemStorage {
75 pub fn new() -> Self {
76 Self::default()
77 }
78}
79
80impl Storage for MemStorage {
81 fn read(&self, path: &Path) -> Result<String> {
82 self.files
83 .read()
84 .unwrap()
85 .get(path)
86 .cloned()
87 .ok_or_else(|| anyhow::anyhow!("file not found: {}", path.display()))
88 }
89
90 fn write(&self, path: &Path, content: &str) -> Result<()> {
91 self.files
92 .write()
93 .unwrap()
94 .insert(path.to_path_buf(), content.to_owned());
95 Ok(())
96 }
97
98 fn delete(&self, path: &Path) -> Result<()> {
99 self.files
100 .write()
101 .unwrap()
102 .remove(path)
103 .ok_or_else(|| anyhow::anyhow!("file not found: {}", path.display()))?;
104 Ok(())
105 }
106
107 fn list(&self, dir: &Path) -> Result<Vec<PathBuf>> {
108 let files = self.files.read().unwrap();
109 Ok(files
110 .keys()
111 .filter(|p| p.parent() == Some(dir))
112 .cloned()
113 .collect())
114 }
115
116 fn create_dir_all(&self, _path: &Path) -> Result<()> {
117 Ok(())
118 }
119
120 fn exists(&self, path: &Path) -> bool {
121 self.files.read().unwrap().contains_key(path)
122 }
123
124 fn rename(&self, from: &Path, to: &Path) -> Result<()> {
125 let mut files = self.files.write().unwrap();
126 let content = files
127 .remove(from)
128 .ok_or_else(|| anyhow::anyhow!("file not found: {}", from.display()))?;
129 files.insert(to.to_path_buf(), content);
130 Ok(())
131 }
132}