This commit is contained in:
Mike Cugini 2021-03-16 00:25:29 -04:00
parent 84c926b8fa
commit 107e692081

View File

@ -15,19 +15,17 @@
use std::error::Error;
use std::fs::File;
use std::io::{self, BufReader};
use std::io::prelude::*;
use std::io::{self, BufReader};
use argh::FromArgs;
#[derive(FromArgs)]
#[argh(
description = "\
#[argh(description = "\
chop off bits of file\n\n\
chop will take produce --count files of --lines lines from the beginning of a\n\
file or stdin. Any remaining lines will be written to a final catchall file.")]
struct Options {
/// number of lines in each chunk
#[argh(option, short = 'n')]
lines: usize,
@ -40,19 +38,17 @@ struct Options {
#[argh(option, short = 'p', default = "String::from(\"\")")]
prefix: String,
/// use numeric suffixes starting with 0, not alphabetic
/// use numeric suffixes starting with 0, not alphabetic
#[argh(switch, short = 'd')]
numeric: bool,
/// use numeric suffixes starting with 0, not alphabetic
/// use numeric suffixes starting with 0, not alphabetic
#[argh(option, long = "numeric-start", default = "0")]
numeric_start: usize,
/// filename to read from, or "-" for stdin (default "-")
#[argh(positional, default = "String::from(\"-\")")]
filename: String,
}
struct AlphabeticSuffixGenerator {
@ -63,12 +59,15 @@ struct AlphabeticSuffixGenerator {
impl AlphabeticSuffixGenerator {
fn new(count: usize) -> AlphabeticSuffixGenerator {
// given 27 letters, minimum number of digits is floor( Log 27 (count) + 1 )
let suffix_length = ((count as f64).log(27f64) + 1.0).floor() as usize;
let suffix_length = ((count as f64).log(27f64) + 1.0).floor() as usize;
let mut suffix = vec![b'a'; suffix_length];
suffix[suffix_length-1] -= 1;
suffix[suffix_length - 1] -= 1;
AlphabeticSuffixGenerator{suffix, remaining: count}
AlphabeticSuffixGenerator {
suffix,
remaining: count,
}
}
}
@ -77,12 +76,12 @@ impl Iterator for AlphabeticSuffixGenerator {
fn next(&mut self) -> Option<String> {
if self.remaining == 0 {
return None
return None;
}
for idx in (0..self.suffix.len()).rev() {
if self.suffix[idx] < b'z' {
self.suffix[idx] += 1;
break
break;
} else {
self.suffix[idx] = b'a';
}
@ -92,27 +91,26 @@ impl Iterator for AlphabeticSuffixGenerator {
}
}
fn try_main() -> Result<(), Box<dyn Error>> {
let opts: Options = argh::from_env();
let input: Box<dyn Read> = match opts.filename.as_str() {
"-" => Box::new(io::stdin()),
path => {
match File::open(path) {
Err(why) => panic!("failed to open {}: {}", path, why),
Ok(file) => Box::new(file),
}
},
path => match File::open(path) {
Err(why) => panic!("failed to open {}: {}", path, why),
Ok(file) => Box::new(file),
},
};
let prefix = match opts.prefix.as_str() {
"" => String::from(""),
_ => opts.prefix + "_",
};
let suffix_gen: Box<dyn Iterator<Item = String>> = if opts.numeric {
Box::new((opts.numeric_start..(opts.numeric_start + opts.count)).map(|num| format!("{}", num)))
Box::new(
(opts.numeric_start..(opts.numeric_start + opts.count)).map(|num| format!("{}", num)),
)
} else {
Box::new(AlphabeticSuffixGenerator::new(opts.count))
};
@ -126,8 +124,8 @@ fn try_main() -> Result<(), Box<dyn Error>> {
match reader.read_line(&mut line)? {
0 => {
eof = true;
break
},
break;
}
_ => {
out_file.write_all(line.as_bytes())?;
line.clear();
@ -140,10 +138,10 @@ fn try_main() -> Result<(), Box<dyn Error>> {
let mut out_file = File::create(format!("{}rest", prefix))?;
for result in reader.lines() {
// lines() strips newline characters, so add one
out_file.write_all((result?+"\n").as_bytes())?;
};
out_file.write_all((result? + "\n").as_bytes())?;
}
}
Ok(())
}