Simplify parsing of --bytes for the split command

This commit is contained in:
Samuel Ainsworth 2021-05-04 00:21:39 -07:00 committed by Sylvestre Ledru
parent ba8f4ea670
commit a9ac7af9e1

View file

@ -261,31 +261,41 @@ struct ByteSplitter {
impl ByteSplitter { impl ByteSplitter {
fn new(settings: &Settings) -> ByteSplitter { fn new(settings: &Settings) -> ByteSplitter {
let mut strategy_param: Vec<char> = settings.strategy_param.chars().collect(); // These multipliers are the same as supported by GNU coreutils with the
let suffix = strategy_param.pop().unwrap(); // exception of zetabytes (2^70) and yottabytes (2^80) as they overflow
let multiplier = match suffix { // standard machine usize (2^64), so we disable for now. Note however
'0'..='9' => 1usize, // that they are supported by the GNU coreutils split. Ignored for now.
'b' => 512usize, let modifiers: Vec<(&str, usize)> = vec![
'k' => 1024usize, ("K", 1024usize),
'm' => 1024usize * 1024usize, ("M", 1024 * 1024),
_ => crash!(1, "invalid number of bytes"), ("G", 1024 * 1024 * 1024),
}; ("T", 1024 * 1024 * 1024 * 1024),
let n = if suffix.is_alphabetic() { ("P", 1024 * 1024 * 1024 * 1024 * 1024),
match strategy_param ("E", 1024 * 1024 * 1024 * 1024 * 1024 * 1024),
.iter() // ("Z", 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024),
.cloned() // ("Y", 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024),
.collect::<String>() ("KB", 1000),
.parse::<usize>() ("MB", 1000 * 1000),
{ ("GB", 1000 * 1000 * 1000),
Ok(a) => a, ("TB", 1000 * 1000 * 1000 * 1000),
Err(e) => crash!(1, "invalid number of bytes: {}", e), ("PB", 1000 * 1000 * 1000 * 1000 * 1000),
} ("EB", 1000 * 1000 * 1000 * 1000 * 1000 * 1000),
} else { // ("ZB", 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000),
match settings.strategy_param.parse::<usize>() { // ("YB", 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000),
Ok(a) => a, ];
Err(e) => crash!(1, "invalid number of bytes: {}", e),
} // This sequential find is acceptable since none of the modifiers are
}; // suffixes of any other modifiers, a la Huffman codes.
let (suffix, multiplier) = modifiers
.iter()
.find(|(suffix, _)| settings.strategy_param.ends_with(suffix))
.unwrap_or(&("", 1));
// Try to parse the actual numeral.
let n = &settings.strategy_param[0..(settings.strategy_param.len() - suffix.len())]
.parse::<usize>()
.unwrap_or_else(|_| crash!(1, "invalid number of bytes"));
ByteSplitter { ByteSplitter {
saved_bytes_to_write: n * multiplier, saved_bytes_to_write: n * multiplier,
bytes_to_write: n * multiplier, bytes_to_write: n * multiplier,