2019-09-02 04:27:56 +00:00
|
|
|
use std::fs::File;
|
|
|
|
use std::io::{self, BufRead, BufReader, Read};
|
|
|
|
use std::path::PathBuf;
|
2019-09-06 15:52:18 +00:00
|
|
|
use std::num::ParseIntError;
|
2019-09-02 04:27:56 +00:00
|
|
|
use structopt::StructOpt;
|
2019-09-06 15:52:18 +00:00
|
|
|
use regex::Regex;
|
|
|
|
|
|
|
|
type Range = (Option<u32>, Option<u32>);
|
|
|
|
|
|
|
|
enum Choice {
|
|
|
|
One(u32),
|
|
|
|
Range
|
|
|
|
}
|
2019-09-02 04:27:56 +00:00
|
|
|
|
|
|
|
#[derive(Debug, StructOpt)]
|
|
|
|
#[structopt(name = "choose", about = "`choose` sections from each line of files")]
|
|
|
|
struct Opt {
|
2019-09-06 15:54:47 +00:00
|
|
|
/// Capture range of fields
|
|
|
|
#[structopt(parse(try_from_str = parse_range))]
|
|
|
|
range: Range,
|
|
|
|
|
2019-09-02 04:27:56 +00:00
|
|
|
/// Specify field separator other than whitespace
|
2019-09-06 15:54:25 +00:00
|
|
|
#[structopt(short, long)]
|
|
|
|
field_separator: Option<String>,
|
2019-09-02 04:27:56 +00:00
|
|
|
|
|
|
|
/// Use inclusive ranges
|
|
|
|
#[structopt(short, long)]
|
|
|
|
inclusive: bool,
|
|
|
|
|
|
|
|
/// Activate debug mode
|
|
|
|
#[structopt(short, long)]
|
|
|
|
debug: bool,
|
|
|
|
|
|
|
|
/// Input file
|
|
|
|
#[structopt(parse(from_os_str))]
|
|
|
|
input: Option<PathBuf>,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
let opt = Opt::from_args();
|
|
|
|
|
|
|
|
let read = match &opt.input {
|
2019-09-06 17:27:38 +00:00
|
|
|
Some(f) => Box::new(File::open(f).expect("Could not open file")) as Box<dyn Read>,
|
|
|
|
None => Box::new(io::stdin()) as Box<dyn Read>,
|
2019-09-02 04:27:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
let buf = BufReader::new(read);
|
|
|
|
|
|
|
|
for line in buf.lines() {
|
|
|
|
println!("{}", line.unwrap());
|
|
|
|
}
|
|
|
|
|
|
|
|
println!("Hello, world!");
|
|
|
|
}
|
2019-09-06 15:54:05 +00:00
|
|
|
|
|
|
|
fn parse_range(src: &str) -> Result<Range, ParseIntError> {
|
|
|
|
let re = Regex::new(r"^(\d*):(\d*)$").unwrap();
|
2019-09-06 17:28:06 +00:00
|
|
|
|
|
|
|
let cap = match re.captures_iter(src).next() {
|
|
|
|
Some(v) => v,
|
|
|
|
None => panic!("failed to parse range argument: {}", src),
|
|
|
|
};
|
|
|
|
|
|
|
|
let start = if cap[1].is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
match cap[1].parse() {
|
|
|
|
Ok(x) => Some(x),
|
|
|
|
Err(e) => panic!("failed to get range argument: {:?}", e),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
let end = if cap[2].is_empty() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
match cap[2].parse() {
|
|
|
|
Ok(x) => Some(x),
|
|
|
|
Err(e) => panic!("failed to get range argument: {:?}", e),
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
return Ok((start, end));
|
2019-09-06 15:54:05 +00:00
|
|
|
}
|