code_mesh_core/storage/
file.rs1use async_trait::async_trait;
4use super::{Storage, StorageError};
5use std::path::PathBuf;
6use tokio::fs;
7
8#[async_trait]
9impl Storage for super::FileStorage {
10 async fn set(&self, key: &str, value: &[u8]) -> Result<(), StorageError> {
11 let path = self.key_to_path(key);
12
13 if let Some(parent) = path.parent() {
15 fs::create_dir_all(parent).await?;
16 }
17
18 fs::write(path, value).await?;
20 Ok(())
21 }
22
23 async fn get(&self, key: &str) -> Result<Option<Vec<u8>>, StorageError> {
24 let path = self.key_to_path(key);
25
26 match fs::read(path).await {
27 Ok(data) => Ok(Some(data)),
28 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(None),
29 Err(e) => Err(e.into()),
30 }
31 }
32
33 async fn delete(&self, key: &str) -> Result<(), StorageError> {
34 let path = self.key_to_path(key);
35
36 match fs::remove_file(path).await {
37 Ok(()) => Ok(()),
38 Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
39 Err(e) => Err(e.into()),
40 }
41 }
42
43 async fn list(&self, prefix: Option<&str>) -> Result<Vec<String>, StorageError> {
44 let mut keys = Vec::new();
45 let mut entries = fs::read_dir(&self.base_path).await?;
46
47 while let Some(entry) = entries.next_entry().await? {
48 if let Some(name) = entry.file_name().to_str() {
49 if let Some(prefix) = prefix {
50 if name.starts_with(prefix) {
51 keys.push(name.to_string());
52 }
53 } else {
54 keys.push(name.to_string());
55 }
56 }
57 }
58
59 Ok(keys)
60 }
61
62 async fn exists(&self, key: &str) -> Result<bool, StorageError> {
63 let path = self.key_to_path(key);
64 Ok(path.exists())
65 }
66}