diff --git a/src/backend/decrypt.rs b/src/backend/decrypt.rs index 4bf0c35..e12759f 100644 --- a/src/backend/decrypt.rs +++ b/src/backend/decrypt.rs @@ -1,6 +1,6 @@ use thiserror::Error; -use super::{FileType, Id, ReadBackend}; +use super::{FileType, Id, IdWithSize, ReadBackend}; use crate::crypto::{CryptoError, Key}; /// RepoError describes the errors that can be returned by accessing this repository @@ -41,6 +41,12 @@ impl ReadBackend for DecryptBackend { self.backend.list(tpe).map_err(RepoError::RepoError) } + fn list_with_size(&self, tpe: FileType) -> Result, Self::Error> { + self.backend + .list_with_size(tpe) + .map_err(RepoError::RepoError) + } + fn read_full(&self, tpe: FileType, id: Id) -> Result, Self::Error> { self.key .decrypt_data(&self.backend.read_full(tpe, id)?) diff --git a/src/backend/local.rs b/src/backend/local.rs index d8d7606..9883ffc 100644 --- a/src/backend/local.rs +++ b/src/backend/local.rs @@ -3,7 +3,7 @@ use std::io::{Read, Seek, SeekFrom}; use std::path::PathBuf; use walkdir::WalkDir; -use super::{FileType, Id, ReadBackend}; +use super::{FileType, Id, IdWithSize, ReadBackend}; #[derive(Clone)] pub struct LocalBackend { @@ -50,6 +50,20 @@ impl ReadBackend for LocalBackend { Ok(walker.collect()) } + fn list_with_size(&self, tpe: FileType) -> Result, Self::Error> { + let walker = WalkDir::new(self.path.join(tpe.name())) + .into_iter() + .filter_map(walkdir::Result::ok) + .filter(|e| e.file_type().is_file()) + .map(|e| { + IdWithSize::new( + Id::from_hex(&e.file_name().to_string_lossy()).unwrap(), + e.metadata().unwrap().len().try_into().unwrap(), + ) + }); + Ok(walker.collect()) + } + fn read_full(&self, tpe: FileType, id: Id) -> Result, Self::Error> { fs::read(self.path(tpe, id)) } diff --git a/src/backend/mod.rs b/src/backend/mod.rs index 81a815e..4ebd92c 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,11 +1,12 @@ +use crate::id::*; +use derive_more::Constructor; + pub mod decrypt; pub mod local; pub use decrypt::DecryptBackend; pub use local::LocalBackend; -use crate::id::*; - #[derive(Clone, Copy)] pub enum FileType { Config, @@ -27,11 +28,18 @@ impl FileType { } } +#[derive(Constructor)] +pub struct IdWithSize { + id: Id, + size: u32, +} + pub trait ReadBackend: Clone { type Error: Send + Sync + std::error::Error + 'static; fn location(&self) -> &str; fn list(&self, tpe: FileType) -> Result, Self::Error>; + fn list_with_size(&self, tpe: FileType) -> Result, Self::Error>; fn read_full(&self, tpe: FileType, id: Id) -> Result, Self::Error>; fn read_partial( &self,