Use LineWriter when input is stdin (#10)

This commit is contained in:
Ryan Geary 2020-06-24 21:08:15 -04:00
parent 2ee77aa848
commit 710b95e866
4 changed files with 32 additions and 42 deletions

View file

@ -1,5 +1,4 @@
use std::convert::TryInto; use std::convert::TryInto;
use std::io::{BufWriter, Write};
use std::iter::FromIterator; use std::iter::FromIterator;
use crate::config::Config; use crate::config::Config;
@ -36,12 +35,7 @@ impl Choice {
} }
} }
pub fn print_choice<W: Write>( pub fn print_choice<W: WriteReceiver>(&self, line: &String, config: &Config, handle: &mut W) {
&self,
line: &String,
config: &Config,
handle: &mut BufWriter<W>,
) {
if config.opt.character_wise { if config.opt.character_wise {
let line_chars = line[0..line.len() - 1].chars(); let line_chars = line[0..line.len() - 1].chars();
self.print_choice_generic(line_chars, config, handle); self.print_choice_generic(line_chars, config, handle);
@ -62,10 +56,10 @@ impl Choice {
self.negative_index self.negative_index
} }
fn print_choice_generic<W, T, I>(&self, mut iter: I, config: &Config, handle: &mut BufWriter<W>) fn print_choice_generic<W, T, I>(&self, mut iter: I, config: &Config, handle: &mut W)
where where
W: Write, W: WriteReceiver,
T: Writeable + Copy, T: Writeable,
I: Iterator<Item = T>, I: Iterator<Item = T>,
{ {
if self.is_reverse_range() && !self.has_negative_index() { if self.is_reverse_range() && !self.has_negative_index() {
@ -81,23 +75,14 @@ impl Choice {
} }
} }
fn print_choice_loop<W, T, I>(iter: I, config: &Config, handle: &mut BufWriter<W>)
where
W: Write,
T: Writeable + Copy,
I: Iterator<Item = T>,
{
Choice::print_choice_loop_max_items(iter, config, handle, isize::max_value());
}
fn print_choice_loop_max_items<W, T, I>( fn print_choice_loop_max_items<W, T, I>(
iter: I, iter: I,
config: &Config, config: &Config,
handle: &mut BufWriter<W>, handle: &mut W,
max_items: isize, max_items: isize,
) where ) where
W: Write, W: WriteReceiver,
T: Writeable + Copy, T: Writeable,
I: Iterator<Item = T>, I: Iterator<Item = T>,
{ {
let mut peek_iter = iter.peekable(); let mut peek_iter = iter.peekable();
@ -111,10 +96,10 @@ impl Choice {
} }
} }
fn print_choice_negative<W, T, I>(&self, iter: I, config: &Config, handle: &mut BufWriter<W>) fn print_choice_negative<W, T, I>(&self, iter: I, config: &Config, handle: &mut W)
where where
W: Write, W: WriteReceiver,
T: Writeable + Copy, T: Writeable,
I: Iterator<Item = T>, I: Iterator<Item = T>,
{ {
let vec = Vec::from_iter(iter); let vec = Vec::from_iter(iter);
@ -136,10 +121,10 @@ impl Choice {
} }
} }
fn print_choice_reverse<W, T, I>(&self, mut iter: I, config: &Config, handle: &mut BufWriter<W>) fn print_choice_reverse<W, T, I>(&self, mut iter: I, config: &Config, handle: &mut W)
where where
W: Write, W: WriteReceiver,
T: Writeable + Copy, T: Writeable,
I: Iterator<Item = T>, I: Iterator<Item = T>,
{ {
if self.end > 0 { if self.end > 0 {

View file

@ -1,5 +1,5 @@
use std::fs::File; use std::fs::File;
use std::io::{self, Read, Write}; use std::io::{self, Read};
use std::process; use std::process;
use structopt::StructOpt; use structopt::StructOpt;
@ -22,6 +22,16 @@ use writer::WriteReceiver;
fn main() { fn main() {
let opt = Opt::from_args(); let opt = Opt::from_args();
let stdout = io::stdout();
let lock = stdout.lock();
match opt.input {
Some(_) => main_generic(opt, &mut io::BufWriter::new(lock)),
None => main_generic(opt, &mut io::LineWriter::new(lock)),
}
}
fn main_generic<W: WriteReceiver>(opt: Opt, handle: &mut W) {
let config = Config::new(opt); let config = Config::new(opt);
let read = match &config.opt.input { let read = match &config.opt.input {
@ -39,16 +49,12 @@ fn main() {
let mut reader = reader::BufReader::new(read); let mut reader = reader::BufReader::new(read);
let mut buffer = String::new(); let mut buffer = String::new();
let stdout = io::stdout();
let lock = stdout.lock();
let mut handle = io::BufWriter::new(lock);
while let Some(line) = reader.read_line(&mut buffer) { while let Some(line) = reader.read_line(&mut buffer) {
match line { match line {
Ok(l) => { Ok(l) => {
let choice_iter = &mut config.opt.choices.iter().peekable(); let choice_iter = &mut config.opt.choices.iter().peekable();
while let Some(choice) = choice_iter.next() { while let Some(choice) = choice_iter.next() {
choice.print_choice(&l, &config, &mut handle); choice.print_choice(&l, &config, handle);
if choice_iter.peek().is_some() { if choice_iter.peek().is_some() {
handle.write_separator(&config); handle.write_separator(&config);
} }

View file

@ -1,4 +1,4 @@
pub trait Writeable { pub trait Writeable: Copy {
fn to_byte_buf(&self) -> Box<[u8]>; fn to_byte_buf(&self) -> Box<[u8]>;
} }

View file

@ -1,14 +1,9 @@
use std::io::{BufWriter, Write}; use std::io::{BufWriter, LineWriter, Write};
use crate::config::Config; use crate::config::Config;
use crate::writeable::Writeable; use crate::writeable::Writeable;
pub trait WriteReceiver { pub trait WriteReceiver: Write {
fn write_choice<Wa: Writeable>(&mut self, b: Wa, config: &Config, print_separator: bool);
fn write_separator(&mut self, config: &Config);
}
impl<W: Write> WriteReceiver for BufWriter<W> {
fn write_choice<Wa: Writeable>(&mut self, b: Wa, config: &Config, print_separator: bool) { fn write_choice<Wa: Writeable>(&mut self, b: Wa, config: &Config, print_separator: bool) {
let num_bytes_written = match self.write(&b.to_byte_buf()) { let num_bytes_written = match self.write(&b.to_byte_buf()) {
Ok(x) => x, Ok(x) => x,
@ -29,3 +24,7 @@ impl<W: Write> WriteReceiver for BufWriter<W> {
} }
} }
} }
impl<W: Write> WriteReceiver for BufWriter<W> {}
impl<W: Write> WriteReceiver for LineWriter<W> {}