diff options
| author | evuez <julien@mulga.net> | 2024-04-03 22:43:16 +0200 | 
|---|---|---|
| committer | evuez <julien@mulga.net> | 2024-04-03 22:43:16 +0200 | 
| commit | 43e1a12b5bce11b4a28a53acca243e35c2be6d3e (patch) | |
| tree | 07d64823718bfee063ab7b3d5721ac1e950ae17c /src/server/storage/backend | |
| download | carton-43e1a12b5bce11b4a28a53acca243e35c2be6d3e.tar.gz | |
Initial commit
Diffstat (limited to 'src/server/storage/backend')
| -rw-r--r-- | src/server/storage/backend/disk.rs | 65 | 
1 files changed, 65 insertions, 0 deletions
diff --git a/src/server/storage/backend/disk.rs b/src/server/storage/backend/disk.rs new file mode 100644 index 0000000..3137376 --- /dev/null +++ b/src/server/storage/backend/disk.rs @@ -0,0 +1,65 @@ +use super::StorageBackend; +use crate::server::blobref::BlobRef; +use crate::server::storage::{Error, Result}; +use log::debug; +use serde::{Deserialize, Serialize}; +use std::{fs, io::ErrorKind, path::PathBuf}; + +pub struct Disk { +    bucket: String, +    pub root: PathBuf, +} + +#[derive(Serialize, Deserialize)] +pub struct Config { +    pub root: PathBuf, +} + +impl StorageBackend for Disk { +    type Config = Config; + +    fn new(bucket: &str, config: &Self::Config) -> Self { +        Self { +            bucket: bucket.to_string(), +            root: config.root.clone().join(bucket), +        } +    } + +    fn put(&self, data: &[u8]) -> Result<BlobRef> { +        let blobref = BlobRef::for_bytes(data); +        debug!("Preparing {blobref}"); + +        if !self.exists(&blobref) { +            let blobpath = self.root.join(blobref.path()); +            let blobdir = blobpath.parent().expect("blobpath should have a parent"); +            debug!("Writing blob to {blobpath:?}"); + +            fs::create_dir_all(blobdir).map_err(|_| Error::Io)?; +            fs::write(blobpath, data).map_err(|_| Error::Io)?; +        } + +        Ok(blobref) +    } + +    fn get(&self, blobref: &BlobRef) -> Result<Option<Vec<u8>>> { +        let blobpath = self.root.join(blobref.path()); + +        match fs::read(blobpath) { +            Ok(contents) => Ok(Some(contents)), +            Err(e) if e.kind() == ErrorKind::NotFound => Ok(None), +            Err(e) => Err(Error::Io), +        } +    } + +    fn exists(&self, blobref: &BlobRef) -> bool { +        self.root.join(blobref.path()).exists() +    } +} + +impl Iterator for Disk { +    type Item = BlobRef; + +    fn next(&mut self) -> Option<Self::Item> { +        todo!() +    } +}  | 
