Add exact size support to the --size filter (#669)

This commit is contained in:
Platon Pronko 2020-12-02 18:04:00 +03:00 committed by David Peter
parent 2338b3bc81
commit e97a1e90cb
4 changed files with 20 additions and 7 deletions

2
doc/fd.1 vendored
View File

@ -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'

View File

@ -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 \

View File

@ -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)
@ -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,
}
}
}
@ -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",

View File

@ -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(
@ -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"],
@ -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)]