diff options
Diffstat (limited to 'src/entry.rs')
-rw-r--r-- | src/entry.rs | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/entry.rs b/src/entry.rs index 2679e42..6ea78bc 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,5 +1,5 @@ -use crate::EntryReadError; use std::path::{Path, PathBuf}; +use crate::*; #[derive(PartialEq)] pub enum EntryType { @@ -10,23 +10,30 @@ pub enum EntryType { pub struct Entry { pub entry_type: EntryType, pub is_symlink: bool, + /// The final segment of the file path, including any file extensions. pub name: String, pub extension: String, + /// The canonical file path, with intermediate symbolic links resolved. pub path: PathBuf, + /// The file path as originally presented to the [Entry] constructor. pub original_path: PathBuf, } + impl Entry { - pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, EntryReadError> { + pub fn from_path(path: impl AsRef<Path>) -> ReadResult<Self> { let path = path.as_ref(); - let metadata = path.metadata()?; - let canonical_path = std::fs::canonicalize(path)?; - let canonical_metadata = canonical_path.metadata()?; + macro_rules! raise { + ($err:expr) => { io_result_to_read_result($err, path)? }; } + + let metadata = raise!(path.metadata()); + let canonical_path = raise!(std::fs::canonicalize(path)); + let canonical_metadata = raise!(canonical_path.metadata()); let entry_type = if canonical_metadata.is_file() { EntryType::File } else if canonical_metadata.is_dir() { EntryType::Directory } else { - return Err(EntryReadError::NotFound); + unreachable!("Canonical metadata must describe either a file or a directory"); }; let name = match path.file_name() { @@ -47,7 +54,11 @@ impl Entry { }) } - /// Splits the filename on the last period, ignoring any period at the + pub fn parent(&self) -> Option<Entry> { + Entry::from_path(self.original_path.parent()?).ok() + } + + /// Split the filename on the last period, ignoring any period at the /// start of the filename. If no extension is found, the extension is empty. pub fn split_name(&self) -> (String, String) { match self.name.rsplit_once(".") { @@ -57,24 +68,18 @@ impl Entry { } pub fn is_file(&self) -> bool { - match self.entry_type { - EntryType::File => true, - _ => false, - } + self.entry_type == EntryType::File } pub fn is_directory(&self) -> bool { - match self.entry_type { - EntryType::Directory => true, - _ => false, - } + self.entry_type == EntryType::Directory } - pub fn read_as_bytes(&self) -> Result<Vec<u8>, EntryReadError> { - return Ok(std::fs::read(&self.path)?); + pub fn read_as_bytes(&self) -> ReadResult<Vec<u8>> { + Ok(io_result_to_read_result(std::fs::read(&self.path), &self.path)?) } - pub fn read_as_utf8_string(&self) -> Result<String, EntryReadError> { + pub fn read_as_utf8(&self) -> ReadResult<String> { return Ok(String::from_utf8_lossy(&self.read_as_bytes()?).to_string()); } } |