From 47b25c05a6be51b93c909d38a19440d1c04ba2f8 Mon Sep 17 00:00:00 2001 From: Ben Bridle Date: Tue, 19 Dec 2023 16:23:29 +1300 Subject: Large collection of changes --- src/entry.rs | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'src/entry.rs') 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>(path: P) -> Result { + pub fn from_path(path: impl AsRef) -> ReadResult { 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::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, EntryReadError> { - return Ok(std::fs::read(&self.path)?); + pub fn read_as_bytes(&self) -> ReadResult> { + Ok(io_result_to_read_result(std::fs::read(&self.path), &self.path)?) } - pub fn read_as_utf8_string(&self) -> Result { + pub fn read_as_utf8(&self) -> ReadResult { return Ok(String::from_utf8_lossy(&self.read_as_bytes()?).to_string()); } } -- cgit v1.2.3-70-g09d2