use super::{ErrorKind, MediaStore, MediaStoreError, Result}; use async_trait::async_trait; use std::path::PathBuf; use tokio::fs::OpenOptions; use tokio::io::{AsyncReadExt, AsyncWriteExt}; #[derive(Clone)] pub struct FileStore { base: PathBuf, } impl From for MediaStoreError { fn from(source: tokio::io::Error) -> Self { Self { source: Some(Box::new(source)), msg: "file I/O error".to_owned(), kind: ErrorKind::Backend, } } } #[async_trait] impl MediaStore for FileStore { async fn write_streaming( &self, domain: url::Host, filename: &str, content: axum::extract::multipart::Field<'_>, ) -> Result<()> { todo!() } async fn read_streaming( &self, domain: url::Host, filename: &str, ) -> Result>> { todo!() } async fn write(&self, domain: url::Host, filename: &str, content: &[u8]) -> Result<()> { let path = self.base.join(format!("{}/{}", domain, filename)); let mut file = OpenOptions::new() .create_new(true) .write(true) .open(path) .await?; Ok(file.write_all(content).await?) } async fn read(&self, domain: url::Host, filename: &str) -> Result> { let path = self.base.join(format!("{}/{}", domain, filename)); let mut file = OpenOptions::new().read(true).open(path).await?; let mut buf: Vec = Vec::default(); file.read_to_end(&mut buf).await?; Ok(buf) } async fn delete(&self, domain: url::Host, filename: &str) -> Result<()> { todo!() } }