use std::borrow::Borrow;
use std::convert::{TryFrom, TryInto};
use std::ops::Deref;
use std::path::{Path, PathBuf};
#[derive(Debug, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct AbsPathBuf(PathBuf);
impl From<AbsPathBuf> for PathBuf {
fn from(abs_path_buf: AbsPathBuf) -> Self {
abs_path_buf.0
}
}
impl Deref for AbsPathBuf {
type Target = AbsPath;
fn deref(&self) -> &Self::Target {
self.as_path()
}
}
impl AsRef<Path> for AbsPathBuf {
fn as_ref(&self) -> &Path {
self.0.as_path()
}
}
impl AsRef<PathBuf> for AbsPathBuf {
fn as_ref(&self) -> &PathBuf {
&self.0
}
}
impl AsRef<AbsPath> for AbsPathBuf {
fn as_ref(&self) -> &AbsPath {
AbsPath::assert_new(self.0.as_path())
}
}
impl TryFrom<PathBuf> for AbsPathBuf {
type Error = PathBuf;
fn try_from(path: PathBuf) -> Result<Self, Self::Error> {
if !path.is_absolute() {
Err(path)
} else {
Ok(AbsPathBuf(path))
}
}
}
impl PartialEq<AbsPath> for AbsPathBuf {
fn eq(&self, other: &AbsPath) -> bool {
self.as_path() == other
}
}
impl Borrow<AbsPath> for AbsPathBuf {
fn borrow(&self) -> &AbsPath {
self.as_path()
}
}
impl AbsPathBuf {
pub fn as_path(&self) -> &AbsPath {
AbsPath::assert_new(self.0.as_path())
}
}
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
#[repr(transparent)]
pub struct AbsPath(Path);
impl Deref for AbsPath {
type Target = Path;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<Path> for AbsPath {
fn as_ref(&self) -> &Path {
&self.0
}
}
impl<'a> TryFrom<&'a Path> for &'a AbsPath {
type Error = &'a Path;
fn try_from(path: &'a Path) -> Result<Self, Self::Error> {
if !path.is_absolute() {
Err(path)
} else {
Ok(AbsPath::assert_new(path))
}
}
}
impl AbsPath {
pub fn assert_new(path: &Path) -> &AbsPath {
assert!(path.is_absolute());
unsafe { &*(path as *const Path as *const AbsPath) }
}
pub fn parent(&self) -> Option<&AbsPath> {
self.0.parent().map(AbsPath::assert_new)
}
pub fn join(&self, path: impl AsRef<Path>) -> AbsPathBuf {
self.as_ref().join(path).try_into().unwrap()
}
pub fn to_path_buf(&self) -> AbsPathBuf {
AbsPathBuf::try_from(self.0.to_path_buf()).unwrap()
}
}