use std_prelude::*;
use super::Result;
use super::{PathAbs, PathArc, PathDir, PathFile};
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serialize", serde(tag = "type", content = "path", rename_all = "lowercase"))]
#[derive(Debug, Clone, Eq, Hash, PartialEq, PartialOrd, Ord)]
pub enum PathType {
File(PathFile),
Dir(PathDir),
}
impl PathType {
pub fn new<P: AsRef<Path>>(path: P) -> Result<PathType> {
let abs = PathAbs::new(&path)?;
PathType::from_abs(abs)
}
pub fn from_abs(abs: PathAbs) -> Result<PathType> {
let ty = abs.metadata()?.file_type();
if ty.is_file() {
Ok(PathType::File(PathFile(abs)))
} else if ty.is_dir() {
Ok(PathType::Dir(PathDir(abs)))
} else {
unreachable!("rust docs: The fs::metadata function follows symbolic links")
}
}
pub fn unwrap_file(self) -> PathFile {
match self {
PathType::File(f) => f,
PathType::Dir(d) => {
panic!("unwrap_file called on {}, which is not a file", d.display())
}
}
}
pub fn unwrap_dir(self) -> PathDir {
match self {
PathType::Dir(d) => d,
PathType::File(f) => panic!(
"unwrap_dir called on {}, which is not a directory",
f.display()
),
}
}
pub fn is_dir(&self) -> bool {
if let PathType::Dir(_) = *self {
true
} else {
false
}
}
pub fn is_file(&self) -> bool {
if let PathType::File(_) = *self {
true
} else {
false
}
}
pub fn mock_file<P: AsRef<Path>>(path: P) -> PathType {
PathType::File(PathFile::mock(path))
}
pub fn mock_dir<P: AsRef<Path>>(path: P) -> PathType {
PathType::Dir(PathDir::mock(path))
}
}
impl AsRef<PathAbs> for PathType {
fn as_ref(&self) -> &PathAbs {
match *self {
PathType::File(ref file) => file.as_ref(),
PathType::Dir(ref dir) => dir.as_ref(),
}
}
}
impl AsRef<PathArc> for PathType {
fn as_ref(&self) -> &PathArc {
let r: &PathAbs = self.as_ref();
r.as_ref()
}
}
impl AsRef<Path> for PathType {
fn as_ref(&self) -> &Path {
let r: &PathAbs = self.as_ref();
r.as_ref()
}
}
impl AsRef<PathBuf> for PathType {
fn as_ref(&self) -> &PathBuf {
let r: &PathAbs = self.as_ref();
r.as_ref()
}
}
impl Deref for PathType {
type Target = PathAbs;
fn deref(&self) -> &PathAbs {
let r: &PathAbs = self.as_ref();
r
}
}
impl Borrow<PathAbs> for PathType {
fn borrow(&self) -> &PathAbs {
self.as_ref()
}
}
impl Borrow<PathArc> for PathType {
fn borrow(&self) -> &PathArc {
self.as_ref()
}
}
impl Borrow<Path> for PathType {
fn borrow(&self) -> &Path {
self.as_ref()
}
}
impl Borrow<PathBuf> for PathType {
fn borrow(&self) -> &PathBuf {
self.as_ref()
}
}
impl<'a> Borrow<PathAbs> for &'a PathType {
fn borrow(&self) -> &PathAbs {
self.as_ref()
}
}
impl<'a> Borrow<PathArc> for &'a PathType {
fn borrow(&self) -> &PathArc {
self.as_ref()
}
}
impl<'a> Borrow<Path> for &'a PathType {
fn borrow(&self) -> &Path {
self.as_ref()
}
}
impl<'a> Borrow<PathBuf> for &'a PathType {
fn borrow(&self) -> &PathBuf {
self.as_ref()
}
}
impl Into<PathAbs> for PathType {
fn into(self) -> PathAbs {
match self {
PathType::File(p) => p.into(),
PathType::Dir(p) => p.into(),
}
}
}
impl Into<PathArc> for PathType {
fn into(self) -> PathArc {
let abs: PathAbs = self.into();
abs.into()
}
}
impl Into<PathBuf> for PathType {
fn into(self) -> PathBuf {
let arc: PathArc = self.into();
arc.into()
}
}