use colored::*;
use std::collections::HashMap;
use std::env;
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::{Component, Path, PathBuf};
use walkdir::WalkDir;
use crate::core::*;
use crate::sys::{self, user};
pub fn abs<T: AsRef<Path>>(path: T) -> Result<PathBuf> {
let path = path.as_ref();
if path.empty() {
return Err(PathError::Empty.into());
}
let mut path_buf = path.expand()?;
path_buf = path_buf.trim_protocol();
path_buf = path_buf.clean()?;
if !path_buf.is_absolute() {
let mut curr = env::current_dir()?;
while let Ok(path) = path_buf.first() {
match path {
Component::CurDir => {
path_buf = path_buf.trim_first();
}
Component::ParentDir => {
curr = curr.dir()?;
path_buf = path_buf.trim_first();
}
_ => return Ok(curr.mash(path_buf)),
}
}
return Ok(curr);
}
Ok(path_buf)
}
pub fn all_dirs<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
let mut paths: Vec<PathBuf> = Vec::new();
let mut distinct = HashMap::<PathBuf, bool>::new();
if abs.is_dir() {
for entry in WalkDir::new(&abs).min_depth(1).follow_links(false).sort_by(|x, y| x.file_name().cmp(y.file_name())) {
let path = entry?.into_path();
if path.is_dir() {
if !distinct.contains_key(&path) {
distinct.insert(path.clone(), true);
paths.push(path);
}
}
}
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn all_files<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
let mut paths: Vec<PathBuf> = Vec::new();
let mut distinct = HashMap::<PathBuf, bool>::new();
if abs.is_dir() {
for entry in WalkDir::new(&abs).min_depth(1).follow_links(false).sort_by(|x, y| x.file_name().cmp(y.file_name())) {
let path = entry?.into_path();
if path.is_file() {
if !distinct.contains_key(&path) {
distinct.insert(path.clone(), true);
paths.push(path);
}
}
}
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn all_paths<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
let mut paths: Vec<PathBuf> = Vec::new();
let mut distinct = HashMap::<PathBuf, bool>::new();
if abs.is_dir() {
for entry in WalkDir::new(&abs).min_depth(1).follow_links(false).sort_by(|x, y| x.file_name().cmp(y.file_name())) {
let path = entry?.into_path();
if !distinct.contains_key(&path) {
distinct.insert(path.clone(), true);
paths.push(path);
}
}
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn cwd() -> Result<PathBuf> {
match env::current_dir() {
Ok(cwd) => Ok(cwd),
Err(err) => Err(err.into()),
}
}
pub fn dirs<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
if abs.is_dir() {
let mut paths: Vec<PathBuf> = Vec::new();
for entry in fs::read_dir(abs)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
paths.push(path.abs()?);
}
}
paths.sort();
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn exists<T: AsRef<Path>>(path: T) -> bool {
match metadata(path) {
Ok(_) => true,
Err(_) => false,
}
}
pub fn expand<T: AsRef<Path>>(path: T) -> Result<PathBuf> {
let mut path = path.as_ref().to_path_buf();
let pathstr = path.to_string()?;
match pathstr.matches("~").count() {
cnt if cnt > 1 => return Err(PathError::multiple_home_symbols(path).into()),
cnt if cnt == 1 && !path.has_prefix("~/") && pathstr != "~" => {
return Err(PathError::invalid_expansion(path).into());
}
cnt if cnt == 1 && pathstr == "~" => {
path = user::home_dir()?;
}
1 => path = user::home_dir()?.mash(&pathstr[2..]),
_ => (),
}
let pathstr = path.to_string()?;
if pathstr.matches("$").some() {
let mut path_buf = PathBuf::new();
for x in path.components() {
match x {
Component::Normal(y) => {
let seg = y.to_string()?;
if seg.starts_with("${") {
let var = env::var(&seg[2..seg.size() - 1])?;
path_buf.push(var);
} else if seg.starts_with("$") {
let var = env::var(&seg[1..])?;
path_buf.push(var);
} else {
path_buf.push(seg);
}
}
_ => path_buf.push(x),
}
}
path = path_buf;
}
Ok(path)
}
pub fn files<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
if abs.is_dir() {
let mut paths: Vec<PathBuf> = Vec::new();
for entry in fs::read_dir(abs)? {
let entry = entry?;
let path = entry.path();
if path.is_file() {
paths.push(path.abs()?);
}
}
paths.sort();
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn is_dir<T: AsRef<Path>>(path: T) -> bool {
match metadata(path) {
Ok(x) => x.is_dir(),
Err(_) => false,
}
}
pub fn is_exec<T: AsRef<Path>>(path: T) -> bool {
match metadata(path) {
Ok(x) => x.permissions().mode() & 0o111 != 0,
Err(_) => false,
}
}
pub fn is_file<T: AsRef<Path>>(path: T) -> bool {
match metadata(path) {
Ok(x) => x.is_file(),
Err(_) => false,
}
}
pub fn is_readonly<T: AsRef<Path>>(path: T) -> bool {
match metadata(path) {
Ok(x) => x.permissions().readonly(),
Err(_) => false,
}
}
pub fn is_symlink<T: AsRef<Path>>(path: T) -> bool {
match path.as_ref().abs() {
Ok(abs) => readlink(abs).is_ok(),
Err(_) => false,
}
}
pub fn is_symlink_dir<T: AsRef<Path>>(path: T) -> bool {
match path.as_ref().abs() {
Ok(abs) => match readlink(&abs) {
Ok(target) => match target.abs_from(&abs) {
Ok(x) => x.is_dir(),
Err(_) => false,
},
Err(_) => false,
},
Err(_) => false,
}
}
pub fn is_symlink_file<T: AsRef<Path>>(path: T) -> bool {
match path.as_ref().abs() {
Ok(abs) => match readlink(&abs) {
Ok(target) => match target.abs_from(&abs) {
Ok(x) => x.is_file(),
Err(_) => false,
},
Err(_) => false,
},
Err(_) => false,
}
}
pub fn gid<T: AsRef<Path>>(path: T) -> Result<u32> {
Ok(metadata(path)?.gid())
}
pub fn glob<T: AsRef<Path>>(src: T) -> Result<Vec<PathBuf>> {
let abs = src.as_ref().abs()?.to_string()?;
let mut paths: Vec<PathBuf> = Vec::new();
for x in glob::glob(&abs)? {
paths.push(x?.abs()?);
}
Ok(paths)
}
pub fn mash<T: AsRef<Path>, U: AsRef<Path>>(dir: T, base: U) -> PathBuf {
dir.as_ref().join(base.as_ref().trim_prefix("/")).components().collect::<PathBuf>()
}
pub fn metadata<T: AsRef<Path>>(path: T) -> Result<fs::Metadata> {
let abs = path.as_ref().abs()?;
let meta = fs::metadata(abs)?;
Ok(meta)
}
pub fn parse_paths<T: AsRef<str>>(value: T) -> Result<Vec<PathBuf>> {
let mut paths: Vec<PathBuf> = Vec::new();
for dir in value.as_ref().split(':') {
let path = match dir == "" {
true => sys::cwd()?,
false => PathBuf::from(dir),
};
paths.push(path);
}
Ok(paths)
}
pub fn paths<T: AsRef<Path>>(path: T) -> Result<Vec<PathBuf>> {
let abs = path.as_ref().abs()?;
if abs.exists() {
if abs.is_dir() {
let mut paths: Vec<PathBuf> = Vec::new();
for entry in fs::read_dir(abs)? {
let entry = entry?;
let path = entry.path();
paths.push(path.abs()?);
}
paths.sort();
return Ok(paths);
}
return Err(PathError::is_not_dir(abs).into());
}
Err(PathError::does_not_exist(abs).into())
}
pub fn readlink<T: AsRef<Path>>(path: T) -> Result<PathBuf> {
let abs = path.as_ref().abs()?;
let abs = fs::read_link(abs)?;
Ok(abs)
}
pub fn uid<T: AsRef<Path>>(path: T) -> Result<u32> {
Ok(metadata(path)?.uid())
}
pub trait PathExt {
fn abs(&self) -> Result<PathBuf>;
fn abs_from<T: AsRef<Path>>(&self, path: T) -> Result<PathBuf>;
fn base(&self) -> Result<String>;
fn chmod(&self, mode: u32) -> Result<()>;
fn clean(&self) -> Result<PathBuf>;
fn concat<T: AsRef<str>>(&self, val: T) -> Result<PathBuf>;
fn dir(&self) -> Result<PathBuf>;
fn empty(&self) -> bool;
fn exists(&self) -> bool;
fn expand(&self) -> Result<PathBuf>;
fn ext(&self) -> Result<String>;
fn first(&self) -> Result<Component>;
fn gid(&self) -> Result<u32>;
fn has<T: AsRef<Path>>(&self, path: T) -> bool;
fn has_prefix<T: AsRef<Path>>(&self, prefix: T) -> bool;
fn has_suffix<T: AsRef<Path>>(&self, suffix: T) -> bool;
fn is_dir(&self) -> bool;
fn is_exec(&self) -> bool;
fn is_file(&self) -> bool;
fn is_readonly(&self) -> bool;
fn is_symlink(&self) -> bool;
fn is_symlink_dir(&self) -> bool;
fn is_symlink_file(&self) -> bool;
fn last(&self) -> Result<Component>;
fn mash<T: AsRef<Path>>(&self, path: T) -> PathBuf;
fn metadata(&self) -> Result<fs::Metadata>;
fn mode(&self) -> Result<u32>;
fn name(&self) -> Result<String>;
fn perms(&self) -> Result<fs::Permissions>;
fn readlink(&self) -> Result<PathBuf>;
fn relative_from<T: AsRef<Path>>(&self, path: T) -> Result<PathBuf>;
fn setperms(&self, perms: fs::Permissions) -> Result<PathBuf>;
fn trim_ext(&self) -> Result<PathBuf>;
fn trim_first(&self) -> PathBuf;
fn trim_last(&self) -> PathBuf;
fn trim_prefix<T: AsRef<Path>>(&self, prefix: T) -> PathBuf;
fn trim_protocol(&self) -> PathBuf;
fn trim_suffix<T: AsRef<Path>>(&self, suffix: T) -> PathBuf;
fn uid(&self) -> Result<u32>;
}
impl PathExt for Path {
fn abs(&self) -> Result<PathBuf> {
abs(self)
}
fn abs_from<T: AsRef<Path>>(&self, base: T) -> Result<PathBuf> {
let base = base.as_ref().abs()?;
if !self.is_absolute() && self != base {
let mut path = base.trim_last();
let mut components = self.components();
loop {
match components.next() {
Some(component) => match component {
Component::ParentDir => path = path.trim_last(),
Component::Normal(x) => return Ok(path.mash(x).mash(components.collect::<PathBuf>()).clean()?),
_ => (),
},
None => return Err(PathError::Empty.into()),
}
}
}
Ok(self.to_path_buf())
}
fn base(&self) -> Result<String> {
self.file_name().ok_or_else(|| PathError::filename_not_found(self))?.to_string()
}
fn chmod(&self, mode: u32) -> Result<()> {
sys::chmod(self, mode)?;
Ok(())
}
fn clean(&self) -> Result<PathBuf> {
let mut cnt = 0;
let mut prev = None;
let mut path_buf = PathBuf::new();
for component in self.components() {
match component {
x if x == Component::CurDir && cnt == 0 => continue,
x if x == Component::ParentDir && cnt > 0 && !prev.has(&Component::ParentDir) => {
match prev.unwrap() {
Component::RootDir => (),
Component::Normal(_) => {
cnt -= 1;
path_buf.pop();
prev = path_buf.components().last();
}
_ => (),
}
continue;
}
_ => {
cnt += 1;
path_buf.push(component);
prev = Some(component);
}
};
}
if path_buf.empty() {
path_buf.push(".");
}
Ok(path_buf)
}
fn concat<T: AsRef<str>>(&self, val: T) -> Result<PathBuf> {
Ok(PathBuf::from(format!("{}{}", self.to_string()?, val.as_ref())))
}
fn dir(&self) -> Result<PathBuf> {
let dir = self.parent().ok_or_else(|| PathError::parent_not_found(self))?;
Ok(dir.to_path_buf())
}
fn empty(&self) -> bool {
self == PathBuf::new()
}
fn exists(&self) -> bool {
exists(&self)
}
fn expand(&self) -> Result<PathBuf> {
expand(&self)
}
fn ext(&self) -> Result<String> {
match self.extension() {
Some(val) => val.to_string(),
None => Err(PathError::extension_not_found(self).into()),
}
}
fn first(&self) -> Result<Component> {
self.components().first_result()
}
fn gid(&self) -> Result<u32> {
gid(&self)
}
fn has<T: AsRef<Path>>(&self, path: T) -> bool {
match (self.to_string(), path.as_ref().to_string()) {
(Ok(base), Ok(path)) => base.contains(&path),
_ => false,
}
}
fn has_prefix<T: AsRef<Path>>(&self, prefix: T) -> bool {
match (self.to_string(), prefix.as_ref().to_string()) {
(Ok(base), Ok(prefix)) => base.starts_with(&prefix),
_ => false,
}
}
fn has_suffix<T: AsRef<Path>>(&self, suffix: T) -> bool {
match (self.to_string(), suffix.as_ref().to_string()) {
(Ok(base), Ok(suffix)) => base.ends_with(&suffix),
_ => false,
}
}
fn is_dir(&self) -> bool {
is_dir(self)
}
fn is_exec(&self) -> bool {
is_exec(self)
}
fn is_file(&self) -> bool {
is_file(self)
}
fn is_readonly(&self) -> bool {
is_readonly(self)
}
fn is_symlink(&self) -> bool {
is_symlink(self)
}
fn is_symlink_dir(&self) -> bool {
is_symlink_dir(self)
}
fn is_symlink_file(&self) -> bool {
is_symlink_file(self)
}
fn last(&self) -> Result<Component> {
self.components().last_result()
}
fn mash<T: AsRef<Path>>(&self, path: T) -> PathBuf {
mash(self, path)
}
fn metadata(&self) -> Result<fs::Metadata> {
let meta = fs::metadata(self)?;
Ok(meta)
}
fn mode(&self) -> Result<u32> {
let perms = self.perms()?;
Ok(perms.mode())
}
fn name(&self) -> Result<String> {
self.trim_ext()?.base()
}
fn perms(&self) -> Result<fs::Permissions> {
Ok(self.metadata()?.permissions())
}
fn readlink(&self) -> Result<PathBuf> {
readlink(self)
}
fn relative_from<T: AsRef<Path>>(&self, base: T) -> Result<PathBuf> {
let path = self.abs()?;
let base = base.as_ref().abs()?;
if path != base {
let mut x = path.components();
let mut y = base.components();
let mut comps: Vec<Component> = vec![];
loop {
match (x.next(), y.next()) {
(None, None) => break,
(Some(a), None) => {
comps.push(a);
comps.extend(x.by_ref());
break;
}
(None, _) => comps.push(Component::ParentDir),
(Some(a), Some(b)) if comps.is_empty() && a == b => (),
(Some(a), Some(b)) if b == Component::CurDir => comps.push(a),
(Some(_), Some(b)) if b == Component::ParentDir => return Ok(path),
(Some(a), Some(_)) => {
for _ in y {
comps.push(Component::ParentDir);
}
comps.push(a);
comps.extend(x.by_ref());
break;
}
}
}
return Ok(comps.iter().collect::<PathBuf>());
}
Ok(path)
}
fn setperms(&self, perms: fs::Permissions) -> Result<PathBuf> {
fs::set_permissions(&self, perms)?;
Ok(self.to_path_buf())
}
fn trim_ext(&self) -> Result<PathBuf> {
Ok(match self.extension() {
Some(val) => self.trim_suffix(format!(".{}", val.to_string()?)),
None => self.to_path_buf(),
})
}
fn trim_first(&self) -> PathBuf {
self.components().drop(1).as_path().to_path_buf()
}
fn trim_last(&self) -> PathBuf {
self.components().drop(-1).as_path().to_path_buf()
}
fn trim_prefix<T: AsRef<Path>>(&self, prefix: T) -> PathBuf {
match (self.to_string(), prefix.as_ref().to_string()) {
(Ok(base), Ok(prefix)) if base.starts_with(&prefix) => PathBuf::from(&base[prefix.size()..]),
_ => self.to_path_buf(),
}
}
fn trim_protocol(&self) -> PathBuf {
match self.to_string() {
Ok(base) => match base.find("//") {
Some(i) => {
let (prefix, suffix) = base.split_at(i + 2);
let lower = prefix.to_lowercase();
let lower = lower.trim_start_matches("file://");
let lower = lower.trim_start_matches("ftp://");
let lower = lower.trim_start_matches("http://");
let lower = lower.trim_start_matches("https://");
if lower != "" {
PathBuf::from(format!("{}{}", prefix, suffix))
} else {
PathBuf::from(suffix)
}
}
_ => PathBuf::from(base),
},
_ => self.to_path_buf(),
}
}
fn trim_suffix<T: AsRef<Path>>(&self, suffix: T) -> PathBuf {
match (self.to_string(), suffix.as_ref().to_string()) {
(Ok(base), Ok(suffix)) if base.ends_with(&suffix) => PathBuf::from(&base[..base.size() - suffix.size()]),
_ => self.to_path_buf(),
}
}
fn uid(&self) -> Result<u32> {
uid(&self)
}
}
pub trait PathColorExt {
fn black(&self) -> Result<ColoredString>;
fn red(&self) -> Result<ColoredString>;
fn green(&self) -> Result<ColoredString>;
fn yellow(&self) -> Result<ColoredString>;
fn blue(&self) -> Result<ColoredString>;
fn magenta(&self) -> Result<ColoredString>;
fn purple(&self) -> Result<ColoredString>;
fn cyan(&self) -> Result<ColoredString>;
fn white(&self) -> Result<ColoredString>;
fn bright_black(&self) -> Result<ColoredString>;
fn bright_red(&self) -> Result<ColoredString>;
fn bright_green(&self) -> Result<ColoredString>;
fn bright_yellow(&self) -> Result<ColoredString>;
fn bright_blue(&self) -> Result<ColoredString>;
fn bright_magenta(&self) -> Result<ColoredString>;
fn bright_purple(&self) -> Result<ColoredString>;
fn bright_cyan(&self) -> Result<ColoredString>;
fn bright_white(&self) -> Result<ColoredString>;
fn color<S: Into<Color>>(&self, color: S) -> Result<ColoredString>;
fn on_black(&self) -> Result<ColoredString>;
fn on_red(&self) -> Result<ColoredString>;
fn on_green(&self) -> Result<ColoredString>;
fn on_yellow(&self) -> Result<ColoredString>;
fn on_blue(&self) -> Result<ColoredString>;
fn on_magenta(&self) -> Result<ColoredString>;
fn on_purple(&self) -> Result<ColoredString>;
fn on_cyan(&self) -> Result<ColoredString>;
fn on_white(&self) -> Result<ColoredString>;
fn on_bright_black(&self) -> Result<ColoredString>;
fn on_bright_red(&self) -> Result<ColoredString>;
fn on_bright_green(&self) -> Result<ColoredString>;
fn on_bright_yellow(&self) -> Result<ColoredString>;
fn on_bright_blue(&self) -> Result<ColoredString>;
fn on_bright_magenta(&self) -> Result<ColoredString>;
fn on_bright_purple(&self) -> Result<ColoredString>;
fn on_bright_cyan(&self) -> Result<ColoredString>;
fn on_bright_white(&self) -> Result<ColoredString>;
fn on_color<S: Into<Color>>(&self, color: S) -> Result<ColoredString>;
fn normal(&self) -> Result<ColoredString>;
fn bold(&self) -> Result<ColoredString>;
fn dimmed(&self) -> Result<ColoredString>;
fn italic(&self) -> Result<ColoredString>;
fn underline(&self) -> Result<ColoredString>;
fn blink(&self) -> Result<ColoredString>;
fn reverse(&self) -> Result<ColoredString>;
fn reversed(&self) -> Result<ColoredString>;
fn hidden(&self) -> Result<ColoredString>;
fn strikethrough(&self) -> Result<ColoredString>;
}
impl PathColorExt for Path {
fn black(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Black))
}
fn red(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Red))
}
fn green(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Green))
}
fn yellow(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Yellow))
}
fn blue(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Blue))
}
fn magenta(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Magenta))
}
fn purple(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Magenta))
}
fn cyan(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::Cyan))
}
fn white(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::White))
}
fn bright_black(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightBlack))
}
fn bright_red(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightRed))
}
fn bright_green(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightGreen))
}
fn bright_yellow(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightYellow))
}
fn bright_blue(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightBlue))
}
fn bright_magenta(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightMagenta))
}
fn bright_purple(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightMagenta))
}
fn bright_cyan(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightCyan))
}
fn bright_white(&self) -> Result<ColoredString> {
Ok(self.to_string()?.color(Color::BrightWhite))
}
fn color<S: Into<Color>>(&self, color: S) -> Result<ColoredString> {
Ok(self.to_string()?.color(color.into()))
}
fn on_black(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Black))
}
fn on_red(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Red))
}
fn on_green(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Green))
}
fn on_yellow(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Yellow))
}
fn on_blue(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Blue))
}
fn on_magenta(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Magenta))
}
fn on_purple(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Magenta))
}
fn on_cyan(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::Cyan))
}
fn on_white(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::White))
}
fn on_bright_black(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightBlack))
}
fn on_bright_red(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightRed))
}
fn on_bright_green(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightGreen))
}
fn on_bright_yellow(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightYellow))
}
fn on_bright_blue(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightBlue))
}
fn on_bright_magenta(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightMagenta))
}
fn on_bright_purple(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightMagenta))
}
fn on_bright_cyan(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightCyan))
}
fn on_bright_white(&self) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(Color::BrightWhite))
}
fn on_color<S: Into<Color>>(&self, color: S) -> Result<ColoredString> {
Ok(self.to_string()?.on_color(color))
}
fn normal(&self) -> Result<ColoredString> {
Ok(self.to_string()?.normal())
}
fn bold(&self) -> Result<ColoredString> {
Ok(self.to_string()?.bold())
}
fn dimmed(&self) -> Result<ColoredString> {
Ok(self.to_string()?.dimmed())
}
fn italic(&self) -> Result<ColoredString> {
Ok(self.to_string()?.italic())
}
fn underline(&self) -> Result<ColoredString> {
Ok(self.to_string()?.underline())
}
fn blink(&self) -> Result<ColoredString> {
Ok(self.to_string()?.blink())
}
fn reverse(&self) -> Result<ColoredString> {
Ok(self.to_string()?.reverse())
}
fn reversed(&self) -> Result<ColoredString> {
Ok(self.to_string()?.reversed())
}
fn hidden(&self) -> Result<ColoredString> {
Ok(self.to_string()?.hidden())
}
fn strikethrough(&self) -> Result<ColoredString> {
Ok(self.to_string()?.strikethrough())
}
}
#[cfg(test)]
mod tests {
use crate::prelude::*;
fn setup() -> PathBuf {
let temp = PathBuf::from("tests/temp").abs().unwrap();
sys::mkdir(&temp).unwrap();
temp
}
#[test]
fn test_abs() {
let home = PathBuf::from(env::var("HOME").unwrap());
let cwd = env::current_dir().unwrap();
let prev = cwd.dir().unwrap();
assert_eq!(sys::abs("..//").unwrap(), prev);
assert_eq!(sys::abs("../").unwrap(), prev);
assert_eq!(sys::abs("..").unwrap(), prev);
assert_eq!(sys::abs(".//").unwrap(), cwd);
assert_eq!(sys::abs("./").unwrap(), cwd);
assert_eq!(sys::abs(".").unwrap(), cwd);
assert_eq!(sys::abs("~").unwrap(), home);
assert_eq!(sys::abs("~/").unwrap(), home);
assert_eq!(sys::abs("foo").unwrap(), cwd.mash("foo"));
assert_eq!(sys::abs("~/foo").unwrap(), home.mash("foo"));
assert_eq!(sys::abs("~/foo/bar/../.").unwrap(), home.mash("foo"));
assert_eq!(sys::abs("~/foo/bar/../").unwrap(), home.mash("foo"));
assert_eq!(sys::abs("~/foo/bar/../blah").unwrap(), home.mash("foo/blah"));
assert_eq!(sys::abs("./../../foo").unwrap(), home.mash("foo"));
assert_eq!(sys::abs("../../foo").unwrap(), home.mash("foo"));
assert!(sys::abs("../../../../../foo").is_err());
}
#[test]
fn test_all_dirs() {
let tmpdir = setup().mash("path_all_dirs");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir1.mash("dir2");
let tmpfile1 = tmpdir.mash("file1");
let tmpfile2 = tmpdir.mash("file2");
assert!(sys::all_dirs("").is_err());
assert!(sys::all_dirs("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::all_dirs(&tmpfile1).is_err());
let dirs = sys::all_dirs(&tmpdir).unwrap();
assert_iter_eq(dirs, vec![tmpdir1, tmpdir2]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_all_files() {
let tmpdir = setup().mash("path_all_files");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir1.mash("dir2");
let tmpfile1 = tmpdir1.mash("file1");
let tmpfile2 = tmpdir2.mash("file2");
assert!(sys::all_files("").is_err());
assert!(sys::all_files("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::all_files(&tmpfile1).is_err());
let files = sys::all_files(&tmpdir).unwrap();
assert_iter_eq(files, vec![tmpfile2, tmpfile1]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_all_paths() {
let tmpdir = setup().mash("path_all_paths");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir1.mash("dir2");
let tmpfile1 = tmpdir1.mash("file1");
let tmpfile2 = tmpdir2.mash("file2");
assert!(sys::all_paths("").is_err());
assert!(sys::all_paths("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::all_paths(&tmpfile1).is_err());
let paths = sys::all_paths(&tmpdir).unwrap();
assert_iter_eq(paths, vec![tmpdir1, tmpdir2, tmpfile2, tmpfile1]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_dirs() {
let tmpdir = setup().mash("path_dirs");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir.mash("dir2");
let tmpfile1 = tmpdir.mash("file1");
let tmpfile2 = tmpdir.mash("file2");
assert!(sys::dirs("").is_err());
assert!(sys::dirs("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::dirs(&tmpfile1).is_err());
let dirs = sys::dirs(&tmpdir).unwrap();
assert_iter_eq(dirs, vec![tmpdir1, tmpdir2]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_exists() {
let tmpdir = setup().mash("path_exists");
let tmpfile = tmpdir.mash("file");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(sys::exists(&tmpfile), false);
assert!(sys::touch(&tmpfile).is_ok());
assert_eq!(sys::exists(&tmpfile), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_files() {
let tmpdir = setup().mash("path_files");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir.mash("dir2");
let tmpfile1 = tmpdir.mash("file1");
let tmpfile2 = tmpdir.mash("file2");
assert!(sys::files("").is_err());
assert!(sys::files("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::files(&tmpfile1).is_err());
let files = sys::files(&tmpdir).unwrap();
assert_iter_eq(files, vec![tmpfile1, tmpfile2]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_uid() {
assert!(sys::uid(".").is_ok());
assert!(Path::new(".").uid().is_ok());
}
#[test]
fn test_gid() {
assert!(sys::gid(".").is_ok());
assert!(Path::new(".").gid().is_ok());
}
#[test]
fn test_is_dir() {
assert_eq!(sys::is_dir("."), true);
assert_eq!(sys::is_dir(setup()), true);
assert_eq!(sys::is_dir("/foobar"), false);
}
#[test]
fn test_is_exec() {
let tmpdir = setup().mash("path_is_exec");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(sys::is_exec(&file1), false);
assert!(sys::touch_p(&file1, 0o644).is_ok());
assert_eq!(file1.mode().unwrap(), 0o100644);
assert_eq!(file1.is_exec(), false);
assert!(sys::chmod_p(&file1).unwrap().add_x().chmod().is_ok());
assert_eq!(file1.mode().unwrap(), 0o100755);
assert_eq!(file1.is_exec(), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_is_file() {
let tmpdir = setup().mash("path_is_file");
let tmpfile = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(sys::is_file(&tmpfile), false);
assert!(sys::touch(&tmpfile).is_ok());
assert_eq!(sys::is_file(tmpfile), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_is_readonly() {
let tmpdir = setup().mash("path_is_readonly");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(sys::is_readonly(&file1), false);
assert!(sys::touch_p(&file1, 0o644).is_ok());
assert_eq!(file1.is_readonly(), false);
assert!(sys::chmod_p(&file1).unwrap().readonly().chmod().is_ok());
assert_eq!(file1.mode().unwrap(), 0o100444);
assert_eq!(sys::is_readonly(&file1), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_is_symlink() {
let tmpdir = setup().mash("path_is_symlink");
let file1 = tmpdir.mash("file1");
let link1 = tmpdir.mash("link1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(sys::is_symlink(&link1), false);
assert!(sys::touch(&file1).is_ok());
assert!(sys::symlink(&link1, &file1).is_ok());
assert_eq!(sys::is_symlink(link1), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_is_symlink_dir() {
let tmpdir = setup().mash("path_is_symlink_dir");
let dir1 = tmpdir.mash("dir1");
let link1 = tmpdir.mash("link1");
let link2 = tmpdir.mash("link2");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&dir1).is_ok());
assert!(sys::symlink(&link1, &dir1).is_ok());
assert_eq!(sys::is_symlink_dir(&link1), true);
assert_eq!(sys::is_symlink_file(&link1), false);
assert!(sys::symlink(&link2, "dir1").is_ok());
assert_eq!(sys::is_symlink_dir(&link2), true);
assert_eq!(sys::is_symlink_file(&link2), false);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_is_symlink_file() {
let tmpdir = setup().mash("path_is_symlink_file");
let file1 = tmpdir.mash("file1");
let link1 = tmpdir.mash("link1");
let link2 = tmpdir.mash("link2");
assert_eq!(sys::is_symlink_file(""), false);
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(sys::symlink(&link1, &file1).is_ok());
assert_eq!(sys::is_symlink_file(&link1), true);
assert_eq!(sys::is_symlink_dir(&link1), false);
assert!(sys::symlink(&link2, "file1").is_ok());
assert_eq!(sys::is_symlink_file(&link2), true);
assert_eq!(sys::is_symlink_dir(&link2), false);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_glob() {
let tmpdir = setup().mash("path_glob");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir.mash("dir2");
let tmpfile1 = tmpdir.mash("file1");
let tmpfile2 = tmpdir.mash("file2");
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
let paths = sys::glob(tmpdir.mash("*")).unwrap();
assert_iter_eq(paths, vec![tmpdir1, tmpdir2, tmpfile1, tmpfile2]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_metadata() {
let meta = sys::metadata(setup()).unwrap();
assert_eq!(meta.is_dir(), true);
}
#[test]
fn test_paths() {
let tmpdir = setup().mash("path_paths");
let tmpdir1 = tmpdir.mash("dir1");
let tmpdir2 = tmpdir.mash("dir2");
let tmpfile1 = tmpdir.mash("file1");
let tmpfile2 = tmpdir.mash("file2");
assert!(sys::paths("").is_err());
assert!(sys::paths("foobar").is_err());
assert!(sys::mkdir(&tmpdir1).is_ok());
assert!(sys::mkdir(&tmpdir2).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert_eq!(tmpdir.is_file(), false);
assert_eq!(tmpdir1.is_dir(), true);
assert_eq!(tmpdir2.is_dir(), true);
assert!(sys::touch(&tmpfile1).is_ok());
assert_eq!(tmpfile1.is_dir(), false);
assert_eq!(tmpfile1.is_file(), true);
assert!(sys::touch(&tmpfile2).is_ok());
assert_eq!(tmpfile2.is_dir(), false);
assert_eq!(tmpfile2.is_file(), true);
assert!(sys::paths(&tmpfile1).is_err());
let paths = sys::paths(&tmpdir).unwrap();
assert_iter_eq(paths, vec![tmpdir1, tmpdir2, tmpfile1, tmpfile2]);
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.exists(), false);
}
#[test]
fn test_parse_paths() {
let paths = vec![PathBuf::from("/foo1"), PathBuf::from("/foo2/bar")];
assert_iter_eq(sys::parse_paths("/foo1:/foo2/bar").unwrap(), paths);
let paths = vec![sys::cwd().unwrap(), PathBuf::from("/foo1"), PathBuf::from("/foo2/bar")];
assert_iter_eq(sys::parse_paths(":/foo1:/foo2/bar").unwrap(), paths);
}
#[test]
fn test_readlink() {
let tmpdir = setup().mash("path_readlink");
let file1 = tmpdir.mash("file1");
let link1 = tmpdir.mash("link1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(sys::symlink(&link1, &file1).is_ok());
assert_eq!(sys::is_symlink_file(&link1), true);
assert_eq!(sys::is_symlink_dir(&link1), false);
assert_eq!(sys::readlink(&link1).unwrap(), file1);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_abs_from() {
let home = PathBuf::from("~").abs().unwrap();
assert!(PathBuf::from("foo").abs_from("").is_err());
assert_eq!(PathBuf::from("/foo").abs_from("foo1").unwrap(), PathBuf::from("/foo"));
assert_eq!(PathBuf::from("foo2").abs_from(home.mash("foo1").abs().unwrap()).unwrap(), home.mash("foo2"));
assert_eq!(PathBuf::from("./foo2").abs_from(home.mash("foo1").abs().unwrap()).unwrap(), home.mash("foo2"));
assert_eq!(PathBuf::from("../foo2").abs_from(home.mash("bar1/foo1").abs().unwrap()).unwrap(), home.mash("foo2"));
assert_eq!(PathBuf::from("bar2/foo2").abs_from(home.mash("bar1/foo1").abs().unwrap()).unwrap(), home.mash("bar1/bar2/foo2"));
assert_eq!(PathBuf::from("../../foo2").abs_from(home.mash("bar1/foo1").abs().unwrap()).unwrap(), home.trim_last().mash("foo2"));
assert_eq!(PathBuf::from("blah1/bar2/foo2").abs_from(home.mash("bar1/foo1").abs().unwrap()).unwrap(), home.mash("bar1/blah1/bar2/foo2"));
}
#[test]
fn test_pathext_base() {
assert_eq!("bar", PathBuf::from("/foo/bar").base().unwrap());
}
#[test]
fn test_pathext_chmod() {
let tmpdir = setup().mash("path_pathbuf_chmod");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(file1.chmod(0o644).is_ok());
assert_eq!(file1.mode().unwrap(), 0o100644);
assert!(file1.chmod(0o555).is_ok());
assert_eq!(file1.mode().unwrap(), 0o100555);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_clean() {
let tests = vec![
("/", "/"),
("/", "//"),
("/", "///"),
(".", ".//"),
("/", "//.."),
("..", "..//"),
("/", "/..//"),
("foo/bar/blah", "foo//bar///blah"),
("/foo/bar/blah", "/foo//bar///blah"),
("/", "/.//./"),
(".", "././/./"),
(".", "./"),
("/", "/./"),
("foo", "./foo"),
("foo/bar", "./foo/./bar"),
("/foo/bar", "/foo/./bar"),
("foo/bar", "foo/bar/."),
("/", "/.."),
("/foo", "/../foo"),
(".", "foo/.."),
("../foo", "../foo"),
("/bar", "/foo/../bar"),
("foo", "foo/bar/.."),
("bar", "foo/../bar"),
("/bar", "/foo/../bar"),
(".", "foo/bar/../../"),
("..", "foo/bar/../../.."),
("/", "/foo/bar/../../.."),
("/", "/foo/bar/../../../.."),
("../..", "foo/bar/../../../.."),
("blah/bar", "foo/bar/../../blah/bar"),
("blah", "foo/bar/../../blah/bar/.."),
("../foo", "../foo"),
("../foo", "../foo/"),
("../foo/bar", "../foo/bar"),
("..", "../foo/.."),
("~/foo", "~/foo"),
];
for test in tests {
assert_eq!(PathBuf::from(test.0), PathBuf::from(test.1).clean().unwrap());
}
}
#[test]
fn test_pathext_concat() {
assert_eq!(Path::new("").concat(".rs").unwrap(), PathBuf::from(".rs"));
assert_eq!(Path::new("foo").concat(".rs").unwrap(), PathBuf::from("foo.rs"));
assert_eq!(Path::new("foo.exe").concat(".rs").unwrap(), PathBuf::from("foo.exe.rs"));
assert_eq!(Path::new("/foo/bar").concat(".rs").unwrap(), PathBuf::from("/foo/bar.rs"));
}
#[test]
fn test_pathext_dirname() {
assert_eq!(PathBuf::from("/").as_path(), PathBuf::from("/foo/").dir().unwrap());
assert_eq!(PathBuf::from("/foo").as_path(), PathBuf::from("/foo/bar").dir().unwrap());
}
#[test]
fn test_pathext_empty() {
assert_eq!(PathBuf::from("").empty(), true);
assert_eq!(PathBuf::from("/foo").empty(), false);
}
#[test]
fn test_pathext_exists() {
assert_eq!(setup().exists(), true);
}
#[test]
fn test_pathext_expand() {
let home = PathBuf::from(env::var("HOME").unwrap());
assert_eq!(PathBuf::from("~/").expand().unwrap(), home);
assert_eq!(PathBuf::from("~").expand().unwrap(), home);
assert!(PathBuf::from("~/foo~").expand().is_err());
assert!(PathBuf::from("~foo").expand().is_err());
assert_eq!(PathBuf::from(""), PathBuf::from("").expand().unwrap());
assert_eq!(PathBuf::from("$XDG_CONFIG_HOME").expand().unwrap(), home.mash(".config"));
assert_eq!(PathBuf::from("${XDG_CONFIG_HOME}").expand().unwrap(), home.mash(".config"));
env::set_var("PATHEXT_EXPAND", "bar");
assert_eq!(PathBuf::from("~/foo/$PATHEXT_EXPAND").expand().unwrap(), home.mash("foo/bar"));
assert_eq!(PathBuf::from("~/foo/${PATHEXT_EXPAND}").expand().unwrap(), home.mash("foo/bar"));
assert_eq!(PathBuf::from("~/foo/$PATHEXT_EXPAND/blah").expand().unwrap(), home.mash("foo/bar/blah"));
}
#[test]
fn test_pathext_ext() {
assert!(PathBuf::from("").ext().is_err());
assert!(PathBuf::from("foo").ext().is_err());
assert_eq!(PathBuf::from("foo.exe").ext().unwrap(), "exe");
assert_eq!(PathBuf::from("/foo/bar.exe").ext().unwrap(), "exe");
}
#[test]
fn test_pathext_first() {
assert_eq!(Component::RootDir, PathBuf::from("/").first().unwrap());
assert_eq!(Component::CurDir, PathBuf::from(".").first().unwrap());
assert_eq!(Component::ParentDir, PathBuf::from("..").first().unwrap());
assert_eq!(Component::Normal(OsStr::new("foo")), PathBuf::from("foo").first().unwrap());
assert_eq!(Component::Normal(OsStr::new("foo")), PathBuf::from("foo/bar").first().unwrap());
}
#[test]
fn test_pathext_has() {
let path = PathBuf::from("/foo/bar");
assert_eq!(path.has("foo"), true);
assert_eq!(path.has("/foo"), true);
assert_eq!(path.has("/"), true);
assert_eq!(path.has("/ba"), true);
assert_eq!(path.has("bob"), false);
}
#[test]
fn test_pathext_has_prefix() {
let path = PathBuf::from("/foo/bar");
assert_eq!(path.has_prefix("/foo"), true);
assert_eq!(path.has_prefix("foo"), false);
}
#[test]
fn test_pathext_has_suffix() {
let path = PathBuf::from("/foo/bar");
assert_eq!(path.has_suffix("/foo"), false);
assert_eq!(path.has_suffix("/bar"), true);
}
#[test]
fn test_pathext_is_dir() {
let tmpdir = setup().mash("path_pathext_is_dir");
assert!(sys::remove_all(&tmpdir).is_ok());
assert_eq!(tmpdir.is_dir(), false);
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(tmpdir.is_dir(), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_is_file() {
let tmpdir = setup().mash("path_pathext_is_file");
let tmpfile = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&tmpfile).is_ok());
assert_eq!(tmpfile.is_file(), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_is_symlink_file() {
let tmpdir = setup().mash("path_pathext_is_symlink_file");
let file1 = tmpdir.mash("file1");
let link1 = tmpdir.mash("link1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert_eq!(link1.is_symlink_file(), false);
assert!(sys::touch(&file1).is_ok());
assert!(sys::symlink(&link1, &file1).is_ok());
assert_eq!(link1.is_symlink_file(), true);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_last() {
assert_eq!(Component::RootDir, PathBuf::from("/").last().unwrap());
assert_eq!(Component::CurDir, PathBuf::from(".").last().unwrap());
assert_eq!(Component::ParentDir, PathBuf::from("..").last().unwrap());
assert_eq!(Component::Normal(OsStr::new("foo")), PathBuf::from("foo").last().unwrap());
assert_eq!(Component::Normal(OsStr::new("bar")), PathBuf::from("/foo/bar").last().unwrap());
}
#[test]
fn test_pathext_metadata() {
let tmpdir = setup().mash("path_pathext_metadata");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(tmpdir.metadata().is_err());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(tmpdir.metadata().is_ok());
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_mash() {
assert_eq!(Path::new("/foo").mash("/bar"), PathBuf::from("/foo/bar"));
assert_eq!(Path::new("/foo").mash("bar/"), PathBuf::from("/foo/bar"));
}
#[test]
fn test_pathext_meta() {
let meta = setup().metadata().unwrap();
assert_eq!(meta.is_dir(), true);
}
#[test]
fn test_pathext_mode() {
let tmpdir = setup().mash("path_pathbuf_mode");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(file1.chmod(0o644).is_ok());
assert_eq!(file1.mode().unwrap(), 0o100644);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_name() {
assert!(PathBuf::from("").name().is_err());
assert_eq!(PathBuf::from("foo").name().unwrap(), "foo");
assert_eq!(PathBuf::from("foo.exe").name().unwrap(), "foo");
assert_eq!(PathBuf::from("/foo/bar.exe").name().unwrap(), "bar");
}
#[test]
fn test_pathext_perms() {
let tmpdir = setup().mash("path_pathbuf_perms");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(file1.chmod(0o644).is_ok());
assert_eq!(file1.perms().unwrap().mode(), 0o100644);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_setperms() {
let tmpdir = setup().mash("path_pathbuf_setperms");
let file1 = tmpdir.mash("file1");
assert!(sys::remove_all(&tmpdir).is_ok());
assert!(sys::mkdir(&tmpdir).is_ok());
assert!(sys::touch(&file1).is_ok());
assert!(file1.chmod(0o644).is_ok());
let mut perms = file1.perms().unwrap();
assert_eq!(perms.mode(), 0o100644);
perms.set_mode(0o555);
assert!(file1.setperms(perms).is_ok());
assert_eq!(file1.mode().unwrap(), 0o100555);
assert!(sys::remove_all(&tmpdir).is_ok());
}
#[test]
fn test_pathext_relative_from() {
let cwd = env::current_dir().unwrap();
assert_eq!(PathBuf::from("bar1").relative_from("bar1").unwrap(), cwd.mash("bar1"));
assert_eq!(PathBuf::from("bar1").relative_from("bar2").unwrap(), PathBuf::from("bar1"));
assert_eq!(PathBuf::from("foo/bar1").relative_from("foo/bar2").unwrap(), PathBuf::from("bar1"));
assert_eq!(PathBuf::from("~/foo/bar1").relative_from("~/foo/bar2").unwrap(), PathBuf::from("bar1"));
assert_eq!(PathBuf::from("../foo/bar1").relative_from("../foo/bar2").unwrap(), PathBuf::from("bar1"));
assert_eq!(PathBuf::from("foo1/bar1").relative_from("foo2/bar2").unwrap(), PathBuf::from("../foo1/bar1"));
assert_eq!(PathBuf::from("blah1/foo1/bar1").relative_from("blah2/foo2/bar2").unwrap(), PathBuf::from("../../blah1/foo1/bar1"));
}
#[test]
fn test_pathext_trim_ext() {
assert_eq!(PathBuf::from("").trim_ext().unwrap(), PathBuf::new());
assert_eq!(PathBuf::from("foo").trim_ext().unwrap(), PathBuf::from("foo"));
assert_eq!(PathBuf::from("foo.exe").trim_ext().unwrap(), PathBuf::from("foo"));
assert_eq!(PathBuf::from("/foo/bar.exe").trim_ext().unwrap(), PathBuf::from("/foo/bar"));
}
#[test]
fn test_pathext_trim_last() {
assert_eq!(PathBuf::new(), PathBuf::from("/").trim_last());
assert_eq!(PathBuf::from("/"), PathBuf::from("/foo").trim_last());
}
#[test]
fn test_pathext_trim_first() {
assert_eq!(PathBuf::new(), PathBuf::from("/").trim_first());
assert_eq!(PathBuf::from("foo"), PathBuf::from("/foo").trim_first());
}
#[test]
fn test_pathext_trim_prefix() {
assert_eq!(PathBuf::from("/").trim_prefix("/"), PathBuf::new());
assert_eq!(Path::new("/foo/bar").trim_prefix("/foo"), PathBuf::from("/bar"));
assert_eq!(PathBuf::from("/").trim_prefix(""), PathBuf::from("/"));
assert_eq!(PathBuf::from("/foo").trim_prefix("blah"), PathBuf::from("/foo"));
}
#[test]
fn test_pathext_trim_protocol() {
assert_eq!(PathBuf::from("/foo"), PathBuf::from("/foo").trim_protocol());
assert_eq!(PathBuf::from("/foo"), PathBuf::from("file:///foo").trim_protocol());
assert_eq!(PathBuf::from("foo"), PathBuf::from("ftp://foo").trim_protocol());
assert_eq!(PathBuf::from("foo"), PathBuf::from("http://foo").trim_protocol());
assert_eq!(PathBuf::from("foo"), PathBuf::from("https://foo").trim_protocol());
assert_eq!(PathBuf::from("Foo"), PathBuf::from("HTTPS://Foo").trim_protocol());
assert_eq!(PathBuf::from("Foo"), PathBuf::from("Https://Foo").trim_protocol());
assert_eq!(PathBuf::from("FoO"), PathBuf::from("HttpS://FoO").trim_protocol());
assert_eq!(PathBuf::from("foo"), PathBuf::from("foo").trim_protocol());
assert_eq!(PathBuf::from("foo/bar"), PathBuf::from("foo/bar").trim_protocol());
assert_eq!(PathBuf::from("foo//bar"), PathBuf::from("foo//bar").trim_protocol());
assert_eq!(PathBuf::from("ntp:://foo"), PathBuf::from("ntp:://foo").trim_protocol());
}
#[test]
fn test_pathext_trim_suffix() {
assert_eq!(PathBuf::new(), PathBuf::from("/").trim_suffix("/"));
assert_eq!(PathBuf::from("/foo"), PathBuf::from("/foo/").trim_suffix("/"));
assert_eq!(PathBuf::from("/foo"), PathBuf::from("/foo").trim_suffix("/"));
}
#[test]
fn test_pathcoloredext() {
assert!(PathBuf::from("foo").black().is_ok());
assert!(PathBuf::from("foo").red().is_ok());
assert!(PathBuf::from("foo").green().is_ok());
assert!(PathBuf::from("foo").yellow().is_ok());
assert!(PathBuf::from("foo").blue().is_ok());
assert!(PathBuf::from("foo").magenta().is_ok());
assert!(PathBuf::from("foo").purple().is_ok());
assert!(PathBuf::from("foo").cyan().is_ok());
assert!(PathBuf::from("foo").white().is_ok());
assert!(PathBuf::from("foo").bright_black().is_ok());
assert!(PathBuf::from("foo").bright_red().is_ok());
assert!(PathBuf::from("foo").bright_green().is_ok());
assert!(PathBuf::from("foo").bright_yellow().is_ok());
assert!(PathBuf::from("foo").bright_blue().is_ok());
assert!(PathBuf::from("foo").bright_magenta().is_ok());
assert!(PathBuf::from("foo").bright_purple().is_ok());
assert!(PathBuf::from("foo").bright_cyan().is_ok());
assert!(PathBuf::from("foo").bright_white().is_ok());
assert!(PathBuf::from("foo").color(Color::Blue).is_ok());
assert!(PathBuf::from("foo").on_black().is_ok());
assert!(PathBuf::from("foo").on_red().is_ok());
assert!(PathBuf::from("foo").on_green().is_ok());
assert!(PathBuf::from("foo").on_yellow().is_ok());
assert!(PathBuf::from("foo").on_blue().is_ok());
assert!(PathBuf::from("foo").on_magenta().is_ok());
assert!(PathBuf::from("foo").on_purple().is_ok());
assert!(PathBuf::from("foo").on_cyan().is_ok());
assert!(PathBuf::from("foo").on_white().is_ok());
assert!(PathBuf::from("foo").on_bright_black().is_ok());
assert!(PathBuf::from("foo").on_bright_red().is_ok());
assert!(PathBuf::from("foo").on_bright_green().is_ok());
assert!(PathBuf::from("foo").on_bright_yellow().is_ok());
assert!(PathBuf::from("foo").on_bright_blue().is_ok());
assert!(PathBuf::from("foo").on_bright_magenta().is_ok());
assert!(PathBuf::from("foo").on_bright_purple().is_ok());
assert!(PathBuf::from("foo").on_bright_cyan().is_ok());
assert!(PathBuf::from("foo").on_bright_white().is_ok());
assert!(PathBuf::from("foo").on_color(Color::Blue).is_ok());
assert!(PathBuf::from("foo").normal().is_ok());
assert!(PathBuf::from("foo").bold().is_ok());
assert!(PathBuf::from("foo").dimmed().is_ok());
assert!(PathBuf::from("foo").italic().is_ok());
assert!(PathBuf::from("foo").underline().is_ok());
assert!(PathBuf::from("foo").blink().is_ok());
assert!(PathBuf::from("foo").reverse().is_ok());
assert!(PathBuf::from("foo").reversed().is_ok());
assert!(PathBuf::from("foo").hidden().is_ok());
assert!(PathBuf::from("foo").strikethrough().is_ok());
}
}