"Fossies" - the Fresh Open Source Software Archive

Member "fd-8.1.1/src/filter/size.rs" (25 May 2020, 9213 Bytes) of package /linux/privat/fd-8.1.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Rust source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "size.rs": 8.0.0_vs_8.1.0.

    1 use lazy_static::lazy_static;
    2 use regex::Regex;
    3 
    4 lazy_static! {
    5     static ref SIZE_CAPTURES: Regex = Regex::new(r"(?i)^([+-])(\d+)(b|[kmgt]i?b?)$").unwrap();
    6 }
    7 
    8 #[derive(Clone, Copy, Debug, PartialEq)]
    9 pub enum SizeFilter {
   10     Max(u64),
   11     Min(u64),
   12 }
   13 
   14 // SI prefixes (powers of 10)
   15 const KILO: u64 = 1000;
   16 const MEGA: u64 = KILO * 1000;
   17 const GIGA: u64 = MEGA * 1000;
   18 const TERA: u64 = GIGA * 1000;
   19 
   20 // Binary prefixes (powers of 2)
   21 const KIBI: u64 = 1024;
   22 const MEBI: u64 = KIBI * 1024;
   23 const GIBI: u64 = MEBI * 1024;
   24 const TEBI: u64 = GIBI * 1024;
   25 
   26 impl SizeFilter {
   27     pub fn from_string(s: &str) -> Option<Self> {
   28         if !SIZE_CAPTURES.is_match(s) {
   29             return None;
   30         }
   31 
   32         let captures = SIZE_CAPTURES.captures(s)?;
   33         let limit_kind = captures.get(1).map_or("+", |m| m.as_str());
   34         let quantity = captures
   35             .get(2)
   36             .and_then(|v| v.as_str().parse::<u64>().ok())?;
   37 
   38         let multiplier = match &captures.get(3).map_or("b", |m| m.as_str()).to_lowercase()[..] {
   39             v if v.starts_with("ki") => KIBI,
   40             v if v.starts_with('k') => KILO,
   41             v if v.starts_with("mi") => MEBI,
   42             v if v.starts_with('m') => MEGA,
   43             v if v.starts_with("gi") => GIBI,
   44             v if v.starts_with('g') => GIGA,
   45             v if v.starts_with("ti") => TEBI,
   46             v if v.starts_with('t') => TERA,
   47             "b" => 1,
   48             _ => return None,
   49         };
   50 
   51         let size = quantity * multiplier;
   52         Some(match limit_kind {
   53             "+" => SizeFilter::Min(size),
   54             _ => SizeFilter::Max(size),
   55         })
   56     }
   57 
   58     pub fn is_within(&self, size: u64) -> bool {
   59         match *self {
   60             SizeFilter::Max(limit) => size <= limit,
   61             SizeFilter::Min(limit) => size >= limit,
   62         }
   63     }
   64 }
   65 
   66 #[cfg(test)]
   67 mod tests {
   68     use super::*;
   69 
   70     macro_rules! gen_size_filter_parse_test {
   71         ($($name: ident: $val: expr,)*) => {
   72             $(
   73                 #[test]
   74                 fn $name() {
   75                     let (txt, expected) = $val;
   76                     let actual = SizeFilter::from_string(txt).unwrap();
   77                     assert_eq!(actual, expected);
   78                 }
   79             )*
   80         };
   81     }
   82 
   83     // Parsing and size conversion tests data. Ensure that each type gets properly interpreted.
   84     // Call with higher base values to ensure expected multiplication (only need a couple)
   85     gen_size_filter_parse_test! {
   86         byte_plus:                ("+1b",     SizeFilter::Min(1)),
   87         byte_plus_multiplier:     ("+10b",    SizeFilter::Min(10)),
   88         byte_minus:               ("-1b",     SizeFilter::Max(1)),
   89         kilo_plus:                ("+1k",     SizeFilter::Min(1000)),
   90         kilo_plus_suffix:         ("+1kb",    SizeFilter::Min(1000)),
   91         kilo_minus:               ("-1k",     SizeFilter::Max(1000)),
   92         kilo_minus_multiplier:    ("-100k",   SizeFilter::Max(100000)),
   93         kilo_minus_suffix:        ("-1kb",    SizeFilter::Max(1000)),
   94         kilo_plus_upper:          ("+1K",     SizeFilter::Min(1000)),
   95         kilo_plus_suffix_upper:   ("+1KB",    SizeFilter::Min(1000)),
   96         kilo_minus_upper:         ("-1K",     SizeFilter::Max(1000)),
   97         kilo_minus_suffix_upper:  ("-1Kb",    SizeFilter::Max(1000)),
   98         kibi_plus:                ("+1ki",    SizeFilter::Min(1024)),
   99         kibi_plus_multiplier:     ("+10ki",   SizeFilter::Min(10240)),
  100         kibi_plus_suffix:         ("+1kib",   SizeFilter::Min(1024)),
  101         kibi_minus:               ("-1ki",    SizeFilter::Max(1024)),
  102         kibi_minus_multiplier:    ("-100ki",  SizeFilter::Max(102400)),
  103         kibi_minus_suffix:        ("-1kib",   SizeFilter::Max(1024)),
  104         kibi_plus_upper:          ("+1KI",    SizeFilter::Min(1024)),
  105         kibi_plus_suffix_upper:   ("+1KiB",   SizeFilter::Min(1024)),
  106         kibi_minus_upper:         ("-1Ki",    SizeFilter::Max(1024)),
  107         kibi_minus_suffix_upper:  ("-1KIB",   SizeFilter::Max(1024)),
  108         mega_plus:                ("+1m",     SizeFilter::Min(1000000)),
  109         mega_plus_suffix:         ("+1mb",    SizeFilter::Min(1000000)),
  110         mega_minus:               ("-1m",     SizeFilter::Max(1000000)),
  111         mega_minus_suffix:        ("-1mb",    SizeFilter::Max(1000000)),
  112         mega_plus_upper:          ("+1M",     SizeFilter::Min(1000000)),
  113         mega_plus_suffix_upper:   ("+1MB",    SizeFilter::Min(1000000)),
  114         mega_minus_upper:         ("-1M",     SizeFilter::Max(1000000)),
  115         mega_minus_suffix_upper:  ("-1Mb",    SizeFilter::Max(1000000)),
  116         mebi_plus:                ("+1mi",    SizeFilter::Min(1048576)),
  117         mebi_plus_suffix:         ("+1mib",   SizeFilter::Min(1048576)),
  118         mebi_minus:               ("-1mi",    SizeFilter::Max(1048576)),
  119         mebi_minus_suffix:        ("-1mib",   SizeFilter::Max(1048576)),
  120         mebi_plus_upper:          ("+1MI",    SizeFilter::Min(1048576)),
  121         mebi_plus_suffix_upper:   ("+1MiB",   SizeFilter::Min(1048576)),
  122         mebi_minus_upper:         ("-1Mi",    SizeFilter::Max(1048576)),
  123         mebi_minus_suffix_upper:  ("-1MIB",   SizeFilter::Max(1048576)),
  124         giga_plus:                ("+1g",     SizeFilter::Min(1000000000)),
  125         giga_plus_suffix:         ("+1gb",    SizeFilter::Min(1000000000)),
  126         giga_minus:               ("-1g",     SizeFilter::Max(1000000000)),
  127         giga_minus_suffix:        ("-1gb",    SizeFilter::Max(1000000000)),
  128         giga_plus_upper:          ("+1G",     SizeFilter::Min(1000000000)),
  129         giga_plus_suffix_upper:   ("+1GB",    SizeFilter::Min(1000000000)),
  130         giga_minus_upper:         ("-1G",     SizeFilter::Max(1000000000)),
  131         giga_minus_suffix_upper:  ("-1Gb",    SizeFilter::Max(1000000000)),
  132         gibi_plus:                ("+1gi",    SizeFilter::Min(1073741824)),
  133         gibi_plus_suffix:         ("+1gib",   SizeFilter::Min(1073741824)),
  134         gibi_minus:               ("-1gi",    SizeFilter::Max(1073741824)),
  135         gibi_minus_suffix:        ("-1gib",   SizeFilter::Max(1073741824)),
  136         gibi_plus_upper:          ("+1GI",    SizeFilter::Min(1073741824)),
  137         gibi_plus_suffix_upper:   ("+1GiB",   SizeFilter::Min(1073741824)),
  138         gibi_minus_upper:         ("-1Gi",    SizeFilter::Max(1073741824)),
  139         gibi_minus_suffix_upper:  ("-1GIB",   SizeFilter::Max(1073741824)),
  140         tera_plus:                ("+1t",     SizeFilter::Min(1000000000000)),
  141         tera_plus_suffix:         ("+1tb",    SizeFilter::Min(1000000000000)),
  142         tera_minus:               ("-1t",     SizeFilter::Max(1000000000000)),
  143         tera_minus_suffix:        ("-1tb",    SizeFilter::Max(1000000000000)),
  144         tera_plus_upper:          ("+1T",     SizeFilter::Min(1000000000000)),
  145         tera_plus_suffix_upper:   ("+1TB",    SizeFilter::Min(1000000000000)),
  146         tera_minus_upper:         ("-1T",     SizeFilter::Max(1000000000000)),
  147         tera_minus_suffix_upper:  ("-1Tb",    SizeFilter::Max(1000000000000)),
  148         tebi_plus:                ("+1ti",    SizeFilter::Min(1099511627776)),
  149         tebi_plus_suffix:         ("+1tib",   SizeFilter::Min(1099511627776)),
  150         tebi_minus:               ("-1ti",    SizeFilter::Max(1099511627776)),
  151         tebi_minus_suffix:        ("-1tib",   SizeFilter::Max(1099511627776)),
  152         tebi_plus_upper:          ("+1TI",    SizeFilter::Min(1099511627776)),
  153         tebi_plus_suffix_upper:   ("+1TiB",   SizeFilter::Min(1099511627776)),
  154         tebi_minus_upper:         ("-1Ti",    SizeFilter::Max(1099511627776)),
  155         tebi_minus_suffix_upper:  ("-1TIB",   SizeFilter::Max(1099511627776)),
  156     }
  157 
  158     /// Invalid parse testing
  159     macro_rules! gen_size_filter_failure {
  160         ($($name:ident: $value:expr,)*) => {
  161             $(
  162                 #[test]
  163                 fn $name() {
  164                     let i = SizeFilter::from_string($value);
  165                     assert!(i.is_none());
  166                 }
  167             )*
  168         };
  169     }
  170 
  171     // Invalid parse data
  172     gen_size_filter_failure! {
  173         ensure_missing_symbol_returns_none: "10M",
  174         ensure_missing_number_returns_none: "+g",
  175         ensure_missing_unit_returns_none: "+18",
  176         ensure_bad_format_returns_none_1: "$10M",
  177         ensure_bad_format_returns_none_2: "badval",
  178         ensure_bad_format_returns_none_3: "9999",
  179         ensure_invalid_unit_returns_none_1: "+50a",
  180         ensure_invalid_unit_returns_none_2: "-10v",
  181         ensure_invalid_unit_returns_none_3: "+1Mv",
  182         ensure_bib_format_returns_none: "+1bib",
  183         ensure_bb_format_returns_none: "+1bb",
  184     }
  185 
  186     #[test]
  187     fn is_within_less_than() {
  188         let f = SizeFilter::from_string("-1k").unwrap();
  189         assert!(f.is_within(999));
  190     }
  191 
  192     #[test]
  193     fn is_within_less_than_equal() {
  194         let f = SizeFilter::from_string("-1k").unwrap();
  195         assert!(f.is_within(1000));
  196     }
  197 
  198     #[test]
  199     fn is_within_greater_than() {
  200         let f = SizeFilter::from_string("+1k").unwrap();
  201         assert!(f.is_within(1001));
  202     }
  203 
  204     #[test]
  205     fn is_within_greater_than_equal() {
  206         let f = SizeFilter::from_string("+1K").unwrap();
  207         assert!(f.is_within(1000));
  208     }
  209 }