fd/src/exec/input.rs

114 lines
3.2 KiB
Rust
Raw Normal View History

2017-10-20 21:54:43 +02:00
use std::path::MAIN_SEPARATOR;
2017-11-03 01:39:03 +01:00
/// Removes the parent component of the path
pub fn basename(path: &str) -> &str {
let mut index = 0;
for (id, character) in path.char_indices() {
if character == MAIN_SEPARATOR {
index = id;
2017-10-20 21:54:43 +02:00
}
2017-11-03 01:39:03 +01:00
}
2017-10-20 21:54:43 +02:00
2017-11-03 01:39:03 +01:00
// FIXME: On Windows, should return what for C:file.txt D:file.txt and \\server\share ?
if index != 0 {
return &path[index + 1..];
2017-10-20 21:54:43 +02:00
}
2017-11-03 01:39:03 +01:00
path
}
/// Removes the extension from the path
pub fn remove_extension(path: &str) -> &str {
let mut has_dir = false;
let mut dir_index = 0;
let mut ext_index = 0;
2017-10-20 21:54:43 +02:00
2017-11-03 01:39:03 +01:00
for (id, character) in path.char_indices() {
if character == MAIN_SEPARATOR {
has_dir = true;
dir_index = id;
2017-10-20 21:54:43 +02:00
}
2017-11-03 01:39:03 +01:00
if character == '.' {
ext_index = id;
2017-10-20 21:54:43 +02:00
}
}
2017-11-03 01:39:03 +01:00
// Account for hidden files and directories
if ext_index != 0 && (!has_dir || dir_index + 2 <= ext_index) {
return &path[0..ext_index];
2017-10-20 21:54:43 +02:00
}
2017-11-03 01:39:03 +01:00
path
}
/// Removes the basename from the path.
pub fn dirname(path: &str) -> &str {
let mut has_dir = false;
let mut index = 0;
for (id, character) in path.char_indices() {
if character == MAIN_SEPARATOR {
has_dir = true;
index = id;
}
2017-10-26 09:18:05 +02:00
}
2017-10-20 21:54:43 +02:00
2017-11-03 01:39:03 +01:00
// FIXME: On Windows, return what for C:file.txt D:file.txt and \\server\share ?
if !has_dir {
"."
} else if index == 0 {
&path[..1]
} else {
&path[0..index]
2017-10-20 21:54:43 +02:00
}
}
#[cfg(test)]
mod path_tests {
use super::*;
2017-10-20 21:54:43 +02:00
fn correct(input: &str) -> String {
2017-11-03 01:39:03 +01:00
input.replace('/', &MAIN_SEPARATOR.to_string())
2017-10-20 21:54:43 +02:00
}
macro_rules! func_tests {
($($name:ident: $func:ident for $input:expr => $output:expr)+) => {
$(
#[test]
fn $name() {
assert_eq!($func(&correct($input)), correct($output));
}
)+
}
2017-10-20 21:54:43 +02:00
}
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 "" => ""
2017-10-20 21:54:43 +02:00
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"
2017-10-20 21:54:43 +02:00
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"
dirname_empty: dirname for "" => "."
2017-10-20 21:54:43 +02:00
}
#[test]
fn dirname_root() {
#[cfg(windows)]
2017-11-03 01:39:03 +01:00
assert_eq!(dirname("C:\\"), "C:");
#[cfg(windows)]
2017-11-03 01:39:03 +01:00
assert_eq!(dirname("\\"), "\\");
#[cfg(not(windows))]
2017-11-03 01:39:03 +01:00
assert_eq!(dirname("/"), "/");
}
2017-10-20 21:54:43 +02:00
}