aboutsummaryrefslogtreecommitdiffstats
path: root/filamento/src/files.rs
diff options
context:
space:
mode:
Diffstat (limited to 'filamento/src/files.rs')
-rw-r--r--filamento/src/files.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/filamento/src/files.rs b/filamento/src/files.rs
new file mode 100644
index 0000000..3acc871
--- /dev/null
+++ b/filamento/src/files.rs
@@ -0,0 +1,77 @@
+use std::{
+ error::Error,
+ path::{Path, PathBuf},
+ sync::Arc,
+};
+
+use tokio::io;
+
+pub trait FileStore {
+ type Err: Clone + Send + Error;
+
+ fn is_stored(
+ &self,
+ name: &str,
+ ) -> impl std::future::Future<Output = Result<bool, Self::Err>> + std::marker::Send;
+ fn store(
+ &self,
+ name: &str,
+ data: &[u8],
+ ) -> impl std::future::Future<Output = Result<(), Self::Err>> + std::marker::Send;
+ fn delete(
+ &self,
+ name: &str,
+ ) -> impl std::future::Future<Output = Result<(), Self::Err>> + std::marker::Send;
+}
+
+#[derive(Clone, Debug)]
+pub struct Files {
+ root: PathBuf,
+}
+
+impl Files {
+ pub fn new(root: impl AsRef<Path>) -> Self {
+ let root = root.as_ref();
+ let root = root.into();
+ Self { root }
+ }
+
+ pub fn root(&self) -> &Path {
+ &self.root
+ }
+}
+
+impl FileStore for Files {
+ type Err = Arc<io::Error>;
+
+ async fn is_stored(&self, name: &str) -> Result<bool, Self::Err> {
+ tracing::debug!("checking if {} is stored", name);
+ // TODO: is this secure ;-;
+ let name = name.replace("/", "").replace(".", "");
+ let res = tokio::fs::try_exists(self.root.join(name))
+ .await
+ .map_err(|err| Arc::new(err));
+ tracing::debug!("file check res: {:?}", res);
+ res
+ }
+
+ async fn store(&self, name: &str, data: &[u8]) -> Result<(), Self::Err> {
+ tracing::debug!("storing {} is stored", name);
+ let name = name.replace("/", "").replace(".", "");
+ let res = tokio::fs::write(self.root.join(name), data)
+ .await
+ .map_err(|err| Arc::new(err));
+ tracing::debug!("file store res: {:?}", res);
+ res
+ }
+
+ async fn delete(&self, name: &str) -> Result<(), Self::Err> {
+ tracing::debug!("deleting {}", name);
+ let name = name.replace("/", "").replace(".", "");
+ let res = tokio::fs::remove_file(self.root.join(name))
+ .await
+ .map_err(|err| Arc::new(err));
+ tracing::debug!("file delete res: {:?}", res);
+ res
+ }
+}