diff options
author | Lars Wirzenius <liw@liw.fi> | 2020-11-08 12:16:36 +0200 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2020-11-08 18:47:38 +0200 |
commit | 3804bc5a3b9456550e1042672f0f79bbfa54f82c (patch) | |
tree | ca0f91f74120129d309a17326aa58dca4f24ee7d | |
parent | 03526de991a34f443c0ecf2a5892a51121de0aca (diff) | |
download | obnam2-3804bc5a3b9456550e1042672f0f79bbfa54f82c.tar.gz |
feat: add FileSystemEntry to store metadata about files, etc
-rw-r--r-- | src/fsentry.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/fsentry.rs b/src/fsentry.rs new file mode 100644 index 0000000..2a5b153 --- /dev/null +++ b/src/fsentry.rs @@ -0,0 +1,118 @@ +use std::path::{Path, PathBuf}; + +/// A file system entry. +/// +/// Represent all backup-relevant the metadata about a file system +/// object: fully qualified pathname, type, length (if applicable), +/// etc. Everything except the content of a regular file or the +/// contents of a directory. +/// +/// This is everything Obnam cares about each file system object, when +/// making a backup. +#[derive(Debug)] +pub struct FilesystemEntry { + kind: FilesystemKind, + path: PathBuf, + len: u64, +} + +impl FilesystemEntry { + fn new(kind: FilesystemKind, path: &Path, len: u64) -> Self { + Self { + path: path.to_path_buf(), + kind, + len, + } + } + + pub fn regular<P>(path: P, len: u64) -> Self + where + P: AsRef<Path>, + { + Self::new(FilesystemKind::Regular, path.as_ref(), len) + } + + pub fn directory<P>(path: P) -> Self + where + P: AsRef<Path>, + { + Self::new(FilesystemKind::Directory, path.as_ref(), 0) + } + + pub fn kind(&self) -> FilesystemKind { + self.kind + } + + pub fn path(&self) -> &Path { + &self.path + } + + pub fn len(&self) -> u64 { + self.len + } +} + +/// Different types of file system entries. +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum FilesystemKind { + Regular, + Directory, +} + +impl FilesystemKind { + pub fn as_code(&self) -> u8 { + match self { + FilesystemKind::Regular => 0, + FilesystemKind::Directory => 1, + } + } + + pub fn from_code(code: u8) -> anyhow::Result<Self> { + match code { + 0 => Ok(FilesystemKind::Regular), + 1 => Ok(FilesystemKind::Directory), + _ => Err(Error::UnknownFileKindCode(code).into()), + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("unknown file kind code {0}")] + UnknownFileKindCode(u8), +} + +#[cfg(test)] +mod test { + use super::{FilesystemEntry, FilesystemKind}; + use std::path::Path; + + #[test] + fn regular_file() { + let filename = Path::new("foo.dat"); + let len = 123; + let e = FilesystemEntry::regular(filename, len); + assert_eq!(e.kind(), FilesystemKind::Regular); + assert_eq!(e.path(), filename); + assert_eq!(e.len(), len); + } + + #[test] + fn directory() { + let filename = Path::new("foo.dat"); + let e = FilesystemEntry::directory(filename); + assert_eq!(e.kind(), FilesystemKind::Directory); + assert_eq!(e.path(), filename); + assert_eq!(e.len(), 0); + } + + #[test] + fn file_kind_regular_round_trips() { + one_file_kind_round_trip(FilesystemKind::Regular); + one_file_kind_round_trip(FilesystemKind::Directory); + } + + fn one_file_kind_round_trip(kind: FilesystemKind) { + assert_eq!(kind, FilesystemKind::from_code(kind.as_code()).unwrap()); + } +} |