committed by
GitHub
parent
0e8926453a
commit
cdfcea6ba8
87
src/utils.rs
87
src/utils.rs
@@ -4,8 +4,8 @@ use anyhow::Result;
|
||||
use log::{debug, error};
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::path::{Component, Path, PathBuf};
|
||||
use std::fmt::Debug;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{ExitStatus, Output};
|
||||
use which_crate;
|
||||
|
||||
@@ -93,93 +93,10 @@ pub fn sudo() -> Option<PathBuf> {
|
||||
which("sudo").or_else(|| which("pkexec"))
|
||||
}
|
||||
|
||||
/// `std::fmt::Display` implementation for `std::path::Path`.
|
||||
///
|
||||
/// This struct differs from `std::path::Display` in that in Windows it takes care of printing backslashes
|
||||
/// instead of slashes and don't print the `\\?` prefix in long paths.
|
||||
pub struct HumanizedPath<'a> {
|
||||
path: &'a Path,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a Path> for HumanizedPath<'a> {
|
||||
fn from(path: &'a Path) -> Self {
|
||||
Self { path }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for HumanizedPath<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
if cfg!(windows) {
|
||||
let mut iterator = self.path.components().peekable();
|
||||
|
||||
while let Some(component) = iterator.next() {
|
||||
let mut print_seperator = iterator.peek().is_some();
|
||||
|
||||
match &component {
|
||||
Component::Normal(c) if *c == "?" => {
|
||||
print_seperator = false;
|
||||
}
|
||||
Component::RootDir | Component::CurDir => {
|
||||
print_seperator = false;
|
||||
}
|
||||
Component::ParentDir => {
|
||||
write!(f, "..")?;
|
||||
}
|
||||
Component::Prefix(p) => {
|
||||
write!(f, "{}", p.as_os_str().to_string_lossy())?;
|
||||
print_seperator = true;
|
||||
}
|
||||
Component::Normal(c) => {
|
||||
write!(f, "{}", c.to_string_lossy())?;
|
||||
}
|
||||
};
|
||||
|
||||
if print_seperator {
|
||||
write!(f, "{}", std::path::MAIN_SEPARATOR)?;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
write!(f, "{}", self.path.display())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn editor() -> String {
|
||||
env::var("EDITOR").unwrap_or_else(|_| String::from(if cfg!(windows) { "notepad" } else { "vi" }))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(windows)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn humanize<P: AsRef<Path>>(path: P) -> String {
|
||||
format!("{}", HumanizedPath::from(path.as_ref()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_just_drive() {
|
||||
assert_eq!("C:\\", humanize("C:\\"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_path() {
|
||||
assert_eq!("C:\\hi", humanize("C:\\hi"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unc() {
|
||||
assert_eq!("\\\\server\\share\\", humanize("\\\\server\\share"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_path() {
|
||||
assert_eq!("C:\\hi", humanize("//?/C:/hi"));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn require<T: AsRef<OsStr> + Debug>(binary_name: T) -> Result<PathBuf> {
|
||||
match which_crate::which(&binary_name) {
|
||||
Ok(path) => {
|
||||
|
||||
Reference in New Issue
Block a user