mirror of
https://github.com/sharkdp/fd
synced 2024-10-14 03:32:31 +00:00
Implement multiple suffixes extension support with tests (#214)
This commit is contained in:
parent
b1bb60ebb9
commit
86fe9977e8
|
@ -25,6 +25,7 @@ mod app;
|
|||
mod exec;
|
||||
mod internal;
|
||||
mod output;
|
||||
mod utils;
|
||||
mod walk;
|
||||
|
||||
#[cfg(windows)]
|
||||
|
@ -152,7 +153,7 @@ fn main() {
|
|||
.collect(),
|
||||
},
|
||||
extensions: matches.values_of("extension").map(|exts| {
|
||||
exts.map(|e| e.trim_left_matches('.').to_lowercase())
|
||||
exts.map(|e| String::from(".") + &e.trim_left_matches('.'))
|
||||
.collect()
|
||||
}),
|
||||
command,
|
||||
|
|
45
src/utils.rs
Normal file
45
src/utils.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
// Copyright (c) 2017 fd developers
|
||||
// Licensed under the Apache License, Version 2.0
|
||||
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0>
|
||||
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
|
||||
// at your option. All files in the project carrying such
|
||||
// notice may not be copied, modified, or distributed except
|
||||
// according to those terms.
|
||||
|
||||
use std::path::Path;
|
||||
use std::iter::Iterator;
|
||||
|
||||
/// Determine if an os string ends with any of the given extensions (case insensitive).
|
||||
pub fn path_has_any_extension<'a, I>(path: &Path, exts: I) -> bool
|
||||
where
|
||||
I: 'a + Iterator<Item = &'a String> + Clone,
|
||||
{
|
||||
// TODO: remove these two lines when we drop support for Rust version < 1.23.
|
||||
#[allow(unused_imports)]
|
||||
use std::ascii::AsciiExt;
|
||||
|
||||
if let Some(ref name) = path.file_name() {
|
||||
if let Some(ref name_str) = name.to_str() {
|
||||
exts.clone().any(|x| {
|
||||
let mut it = name_str.chars().rev();
|
||||
|
||||
if x.chars()
|
||||
.rev()
|
||||
.zip(&mut it)
|
||||
.all(|(a, b)| a.eq_ignore_ascii_case(&b))
|
||||
{
|
||||
match it.next() {
|
||||
Some('/') | None => false,
|
||||
_ => true,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
|
@ -11,6 +11,7 @@ extern crate ctrlc;
|
|||
use exec;
|
||||
use fshelper;
|
||||
use internal::{error, FdOptions, EXITCODE_SIGINT, MAX_BUFFER_LENGTH};
|
||||
use utils::path_has_any_extension;
|
||||
use output;
|
||||
|
||||
use std::process;
|
||||
|
@ -214,10 +215,7 @@ pub fn scan(path_vec: &[PathBuf], pattern: Arc<Regex>, config: Arc<FdOptions>) {
|
|||
|
||||
// Filter out unwanted extensions.
|
||||
if let Some(ref filter_exts) = config.extensions {
|
||||
let entry_ext = entry_path
|
||||
.extension()
|
||||
.map(|e| e.to_string_lossy().to_lowercase());
|
||||
if entry_ext.map_or(true, |ext| !filter_exts.contains(&ext)) {
|
||||
if !path_has_any_extension(entry_path, filter_exts.iter()) {
|
||||
return ignore::WalkState::Continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -530,6 +530,28 @@ fn test_extension() {
|
|||
te.assert_output(&["--extension", ".foo", "a"], "a.foo");
|
||||
|
||||
te.assert_output(&["--extension", "foo2"], "one/two/C.Foo2");
|
||||
|
||||
let te2 = TestEnv::new(&[], &["spam.bar.baz", "egg.bar.baz", "yolk.bar.baz.sig"]);
|
||||
|
||||
te2.assert_output(
|
||||
&["--extension", ".bar.baz"],
|
||||
"spam.bar.baz
|
||||
egg.bar.baz",
|
||||
);
|
||||
|
||||
te2.assert_output(&["--extension", "sig"], "yolk.bar.baz.sig");
|
||||
|
||||
te2.assert_output(&["--extension", "bar.baz.sig"], "yolk.bar.baz.sig");
|
||||
|
||||
let te3 = TestEnv::new(&[], &["latin1.e\u{301}xt", "smiley.☻"]);
|
||||
|
||||
te3.assert_output(&["--extension", "☻"], "smiley.☻");
|
||||
|
||||
te3.assert_output(&["--extension", ".e\u{301}xt"], "latin1.e\u{301}xt");
|
||||
|
||||
let te4 = TestEnv::new(&[], &[".hidden", "test.hidden"]);
|
||||
|
||||
te4.assert_output(&["--hidden", "--extension", ".hidden"], "test.hidden");
|
||||
}
|
||||
|
||||
/// Symlinks misc
|
||||
|
|
Loading…
Reference in a new issue