use crate::path::{AsPathView, PathBufLike, PathInner}; pub trait PathLike<'p> where Self: Copy + AsPathView<'p, Self::View<'p>>, { type Inner: PathInner<'p>; type Owned: PathBufLike + Into; type View<'a>; type Components<'a>: AsPathView<'a, Self::View<'a>> + Clone + DoubleEndedIterator; type Display<'a>: std::fmt::Display; fn components(self) -> Self::Components<'p>; fn default() -> Self; fn display(self) -> Self::Display<'p>; fn encoded_bytes(self) -> &'p [u8]; fn extension(self) -> Option; fn file_name(self) -> Option; fn file_stem(self) -> Option; unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self; fn is_empty(self) -> bool { self.encoded_bytes().is_empty() } #[cfg(unix)] fn is_hidden(self) -> bool { self.file_name().is_some_and(|n| n.encoded_bytes().first() == Some(&b'.')) } fn join<'a, T>(self, base: T) -> Self::Owned where T: AsPathView<'a, Self::View<'a>>; fn len(self) -> usize { self.encoded_bytes().len() } fn owned(self) -> Self::Owned; fn parent(self) -> Option; fn strip_prefix<'a, T>(self, base: T) -> Option where T: AsPathView<'a, Self::View<'a>>; } impl<'p> PathLike<'p> for &'p std::path::Path { type Components<'a> = std::path::Components<'a>; type Display<'a> = std::path::Display<'a>; type Inner = &'p std::ffi::OsStr; type Owned = std::path::PathBuf; type View<'a> = &'a std::path::Path; fn components(self) -> Self::Components<'p> { self.components() } fn default() -> Self { std::path::Path::new("") } fn display(self) -> Self::Display<'p> { self.display() } fn encoded_bytes(self) -> &'p [u8] { self.as_os_str().as_encoded_bytes() } fn extension(self) -> Option { self.extension() } fn file_name(self) -> Option { self.file_name() } fn file_stem(self) -> Option { self.file_stem() } unsafe fn from_encoded_bytes(bytes: &'p [u8]) -> Self { std::path::Path::new(unsafe { std::ffi::OsStr::from_encoded_bytes_unchecked(bytes) }) } fn join<'a, T>(self, base: T) -> Self::Owned where T: AsPathView<'a, Self::View<'a>>, { self.join(base.as_path_view()) } fn owned(self) -> Self::Owned { self.to_path_buf() } fn parent(self) -> Option { self.parent() } fn strip_prefix<'a, T>(self, base: T) -> Option where T: AsPathView<'a, Self::View<'a>>, { self.strip_prefix(base.as_path_view()).ok() } }