Skip to content

Commit

Permalink
Add exact size support to the --size filter (sharkdp#669)
Browse files Browse the repository at this point in the history
  • Loading branch information
Rogach committed Dec 2, 2020
1 parent 9412648 commit 96c5052
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
2 changes: 2 additions & 0 deletions doc/fd.1
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ Limit results based on the size of files using the format
file size must be greater than or equal to this
.IP '-'
file size must be less than or equal to this
.P
If neither '+' nor '-' is specified, file size must be exactly equal to this.
.IP 'NUM'
The numeric size (e.g. 500)
.IP 'UNIT'
Expand Down
3 changes: 2 additions & 1 deletion src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,8 @@ pub fn build_app() -> App<'static, 'static> {
.long_help(
"Limit results based on the size of files using the format <+-><NUM><UNIT>.\n \
'+': file size must be greater than or equal to this\n \
'-': file size must be less than or equal to this\n \
'-': file size must be less than or equal to this\n\
If neither '+' nor '-' is specified, file size must be exactly equal to this.\n \
'NUM': The numeric size (e.g. 500)\n \
'UNIT': The units for NUM. They are not case-sensitive.\n\
Allowed unit values:\n \
Expand Down
15 changes: 9 additions & 6 deletions src/filter/size.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ use lazy_static::lazy_static;
use regex::Regex;

lazy_static! {
static ref SIZE_CAPTURES: Regex = Regex::new(r"(?i)^([+-])(\d+)(b|[kmgt]i?b?)$").unwrap();
static ref SIZE_CAPTURES: Regex = Regex::new(r"(?i)^([+-]?)(\d+)(b|[kmgt]i?b?)$").unwrap();
}

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum SizeFilter {
Max(u64),
Min(u64),
Equals(u64),
}

// SI prefixes (powers of 10)
Expand Down Expand Up @@ -49,16 +50,19 @@ impl SizeFilter {
};

let size = quantity * multiplier;
Some(match limit_kind {
"+" => SizeFilter::Min(size),
_ => SizeFilter::Max(size),
})
match limit_kind {
"+" => Some(SizeFilter::Min(size)),
"-" => Some(SizeFilter::Max(size)),
"" => Some(SizeFilter::Equals(size)),
_ => None
}
}

pub fn is_within(&self, size: u64) -> bool {
match *self {
SizeFilter::Max(limit) => size <= limit,
SizeFilter::Min(limit) => size >= limit,
SizeFilter::Equals(limit) => size == limit,
}
}
}
Expand Down Expand Up @@ -170,7 +174,6 @@ mod tests {

// Invalid parse data
gen_size_filter_failure! {
ensure_missing_symbol_returns_none: "10M",
ensure_missing_number_returns_none: "+g",
ensure_missing_unit_returns_none: "+18",
ensure_bad_format_returns_none_1: "$10M",
Expand Down
7 changes: 7 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,9 @@ fn test_size() {

// Zero sized files.
te.assert_output(&["", "--size", "-0B"], "0_bytes.foo");
te.assert_output(&["", "--size", "0B"], "0_bytes.foo");
te.assert_output(&["", "--size=0B"], "0_bytes.foo");
te.assert_output(&["", "-S", "0B"], "0_bytes.foo");

// Files with 2 bytes or more.
te.assert_output(
Expand All @@ -1403,6 +1406,9 @@ fn test_size() {
// Files with size between 1 byte and 11 bytes.
te.assert_output(&["", "--size", "+1B", "--size", "-11B"], "11_bytes.foo");

// Files with size equal 11 bytes.
te.assert_output(&["", "--size", "11B"], "11_bytes.foo");

// Files with size between 1 byte and 30 bytes.
te.assert_output(
&["", "--size", "+1B", "--size", "-30B"],
Expand Down Expand Up @@ -1434,6 +1440,7 @@ fn test_size() {

// Files with size equal 4 kibibytes.
te.assert_output(&["", "--size", "+4ki", "--size", "-4ki"], "4_kibibytes.foo");
te.assert_output(&["", "--size", "4ki"], "4_kibibytes.foo");
}

#[cfg(test)]
Expand Down

0 comments on commit 96c5052

Please sign in to comment.