From aa85a4e665c56d00830d948465e396d566dab0c1 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Sun, 31 May 2020 15:38:58 -0700 Subject: implement aft-head --- src/bin/aft-head.rs | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) (limited to 'src/bin') diff --git a/src/bin/aft-head.rs b/src/bin/aft-head.rs index b8c848c..3fecfa2 100644 --- a/src/bin/aft-head.rs +++ b/src/bin/aft-head.rs @@ -1,8 +1,71 @@ - /* * Takes the first n lines of input, passes to stdout. */ -fn main() { - println!("Hello, world2!"); +use std::error::Error; +use std::io::{self, Read, Write, BufRead}; +use structopt::StructOpt; +use std::path::PathBuf; + +#[derive(StructOpt)] +#[structopt(rename_all = "kebab-case", about = "take first N rows of input (AFT-aware)" )] +struct Opt { + #[structopt(long = "--lines", short = "-n", default_value = "10")] + lines: u64, + + #[structopt(parse(from_os_str))] + input: Option, +} + +fn main() -> Result<(), Box> { + + let opt = Opt::from_args(); + + // treat "-" as "use stdin" + let input = match opt.input { + Some(s) if s.to_string_lossy() == "-" => None, + other => other, + }; + let stdin = io::stdin(); + let stdin = stdin.lock(); + let mut input: Box = match input { + None => { + Box::new(io::BufReader::new(stdin)) + }, + Some(path) => { + let f = std::fs::File::open(path)?; + Box::new(io::BufReader::new(f)) + }, + }; + let mut stdout = io::stdout(); + + // read first byte of input to check if we are getting AFT; if not just pass through + let mut first_byte = [0; 1]; + let got = input.read(&mut first_byte)?; + if got != 1 { + panic!("couldn't read a byte from input"); + }; + + let is_aft = first_byte[0] == 0x01; + if !is_aft { + // simple implementation of lines + stdout.write(&first_byte)?; + for l in input.lines().take(opt.lines as usize) { + writeln!(stdout, "{}", l?)?; + } + return Ok(()) + }; + + let mut header_bytes = vec![]; + // TODO: sanity limit on length + input.read_until(0x02, &mut header_bytes)?; + if header_bytes[header_bytes.len()-1] != 0x02 { + panic!("expected an AFT header"); + }; + stdout.write(&first_byte)?; + stdout.write(&header_bytes)?; + for l in input.lines().take(opt.lines as usize) { + writeln!(stdout, "{}", l?)?; + } + Ok(()) } -- cgit v1.2.3