fd/src/exec/input.rs

88 lines
2.8 KiB
Rust

use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use crate::filesystem::strip_current_dir;
/// Removes the parent component of the path
pub fn basename(path: &Path) -> &OsStr {
path.file_name().unwrap_or(path.as_os_str())
}
/// Removes the extension from the path
pub fn remove_extension(path: &Path) -> OsString {
let dirname = dirname(path);
let stem = path.file_stem().unwrap_or(path.as_os_str());
let path = PathBuf::from(dirname).join(stem);
strip_current_dir(&path).to_owned().into_os_string()
}
/// Removes the basename from the path.
pub fn dirname(path: &Path) -> OsString {
path.parent()
.map(|p| {
if p == OsStr::new("") {
OsString::from(".")
} else {
p.as_os_str().to_owned()
}
})
.unwrap_or_else(|| path.as_os_str().to_owned())
}
#[cfg(test)]
mod path_tests {
use super::*;
use std::path::MAIN_SEPARATOR_STR;
fn correct(input: &str) -> String {
input.replace('/', MAIN_SEPARATOR_STR)
}
macro_rules! func_tests {
($($name:ident: $func:ident for $input:expr => $output:expr)+) => {
$(
#[test]
fn $name() {
let input_path = PathBuf::from(&correct($input));
let output_string = OsString::from(correct($output));
assert_eq!($func(&input_path), output_string);
}
)+
}
}
func_tests! {
remove_ext_simple: remove_extension for "foo.txt" => "foo"
remove_ext_dir: remove_extension for "dir/foo.txt" => "dir/foo"
hidden: remove_extension for ".foo" => ".foo"
remove_ext_utf8: remove_extension for "💖.txt" => "💖"
remove_ext_empty: remove_extension for "" => ""
basename_simple: basename for "foo.txt" => "foo.txt"
basename_dir: basename for "dir/foo.txt" => "foo.txt"
basename_empty: basename for "" => ""
basename_utf8_0: basename for "💖/foo.txt" => "foo.txt"
basename_utf8_1: basename for "dir/💖.txt" => "💖.txt"
dirname_simple: dirname for "foo.txt" => "."
dirname_dir: dirname for "dir/foo.txt" => "dir"
dirname_utf8_0: dirname for "💖/foo.txt" => "💖"
dirname_utf8_1: dirname for "dir/💖.txt" => "dir"
}
#[test]
#[cfg(windows)]
fn dirname_root() {
assert_eq!(dirname(&PathBuf::from("C:")), OsString::from("C:"));
assert_eq!(dirname(&PathBuf::from("\\")), OsString::from("\\"));
}
#[test]
#[cfg(not(windows))]
fn dirname_root() {
assert_eq!(dirname(&PathBuf::from("/")), OsString::from("/"));
}
}