use std::convert::AsRef;
use std::io;
use std::path::Path;
use super::PathAbs;
use file::PathFile;
use dir::PathDir;
#[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) -> io::Result<PathType> {
let abs = PathAbs::new(path)?;
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 {
Err(io::Error::new(
io::ErrorKind::InvalidInput,
"path is not a dir or a file",
))
}
}
pub fn unwrap_file(self) -> PathFile {
if let PathType::File(f) = self {
f
} else {
panic!("unwrap_file called on path that is not a file");
}
}
pub fn unwrap_dir(self) -> PathDir {
if let PathType::Dir(d) = self {
d
} else {
panic!("unwrap_dir called on path that is not a dir");
}
}
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))
}
}