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 {
|
|
|
|
Some(f) => Box::new(File::open(f).expect("Could not open file")) as Box<Read>,
|
|
|
|
None => Box::new(io::stdin()) as Box<Read>,
|
|
|
|
};
|
|
|
|
|
|
|
|
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();
|
|
|
|
let cap = re.captures_iter(src).next().unwrap();
|
|
|
|
return Ok((Some(cap[1].parse()?), Some(cap[2].parse()?)));
|
|
|
|
}
|