use std::{ borrow::Borrow, ops::{Deref, DerefMut}, path::PathBuf, }; /// Directory Pointer Data pub trait DirPtrData { /// Fix the given path /// /// Returns Some(path): use the fixed path /// Returns None: path cannot be fixed, this pointer is invalid #[doc(hidden)] fn fix(raw_path: PathBuf) -> Option; } #[derive(Debug, Default, Clone)] pub struct DirPtr { /// Whether the current directory pointer is valid valid: bool, /// Data for the directory pointer data: Data, /// Path to the directory path: PathBuf, } impl DirPtr { /// Get a reference to the directory pointer's path pub fn path_ref(&self) -> &PathBuf { &self.path } /// Get the directory pointer's path pub fn path(&self) -> PathBuf { self.path.clone() } /// Returns whether the directory pointer is valid pub fn is_valid(&self) -> bool { self.valid } } impl DirPtr { /// Create a new directory pointer with the given path and default data pub fn new(path: impl Into) -> Self { let path = path.into(); let fixed = Data::fix(path.clone()); Self { valid: fixed.is_some(), data: Data::default(), path: fixed.unwrap_or(path), } } } impl AsRef> for DirPtr { fn as_ref(&self) -> &DirPtr { self } } impl Deref for DirPtr { type Target = Data; fn deref(&self) -> &Self::Target { &self.data } } impl DerefMut for DirPtr { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.data } } impl Borrow for DirPtr { fn borrow(&self) -> &Data { &self.data } } /// Create a new directory pointer with the given path and default data pub fn dir_ptr(path: impl Into) -> DirPtr { DirPtr::new(path) }