1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
use crate::*; #[derive(Debug, Clone)] pub struct LocalLocation { path: String, } impl LocalLocation { pub async fn new(path: &str) -> Result<Self> { let this = Self { path: util::streamline(path), }; tokio::fs::create_dir_all(&this.path).await?; Ok(this) } } #[async_trait::async_trait(?Send)] impl Adapter for LocalLocation { async fn containers(&self) -> Result<Vec<String>> { let mut res = tokio::fs::read_dir(&self.path).await?; let mut containers = vec![]; while let Some(con) = res.next_entry().await? { if let Some(name) = con.file_name().to_str() { containers.push(name.to_string()); } } Ok(containers) } async fn create_container(&self, container: &str) -> Result<()> { let mut path = self.path.clone(); path.push('/'); path.push_str(&util::streamline(container)); if let Err(e) = tokio::fs::create_dir(path).await { if e.kind() != std::io::ErrorKind::AlreadyExists { return Err(e.into()); } } Ok(()) } async fn remove_container(&self, container: &str) -> Result<()> { let mut path = self.path.clone(); path.push('/'); path.push_str(&util::streamline(container)); tokio::fs::remove_dir_all(path).await?; Ok(()) } async fn items(&self, container: &str) -> Result<Vec<String>> { let container = util::streamline(container); let mut path = String::from(&self.path); path.push('/'); path.push_str(&container); let mut res = tokio::fs::read_dir(&path).await?; let mut containers = vec![]; while let Some(con) = res.next_entry().await? { if let Some(name) = con.file_name().to_str() { containers.push(name.to_string()); } } Ok(containers) } async fn create_item( &self, container: &str, item: &str, reader: &mut (impl tokio::io::AsyncRead + Unpin), ) -> Result<()> { let container = util::streamline(container); let item = util::streamline_item(item)?; let mut path = String::from(&self.path); path.push('/'); path.push_str(&container); path.push('/'); path.push_str(&item); let mut file = tokio::fs::File::create(path).await?; tokio::io::copy(reader, &mut file).await?; Ok(()) } async fn read_item( &self, container: &str, item: &str, ) -> Result<Box<dyn tokio::io::AsyncRead + Unpin>> { let container = util::streamline(container); let item = util::streamline_item(item)?; let mut path = String::from(&self.path); path.push('/'); path.push_str(&container); path.push('/'); path.push_str(&item); let file = tokio::fs::File::open(path).await?; Ok(Box::new(file)) } async fn remove_item(&self, container: &str, item: &str) -> Result<()> { let container = util::streamline(container); let item = util::streamline_item(item)?; let mut path = String::from(&self.path); path.push('/'); path.push_str(&container); path.push('/'); path.push_str(&item); tokio::fs::remove_file(path).await?; Ok(()) } }