Extract most shared logic into SimplePrinter

This should hopefully allow for more command line options, like no
color, omitting line number and file names for better scriptability.
This commit is contained in:
Cameron Cordes
2020-05-19 23:23:15 -04:00
parent 263dad91da
commit ee3e61b76d
2 changed files with 84 additions and 27 deletions

View File

@@ -9,8 +9,11 @@ pub struct FileMatch {
impl FileMatch { impl FileMatch {
pub fn print(&self, config: &Config) { pub fn print(&self, config: &Config) {
let cp = ColorPrinter {}; let cp = ColorPrinter {
cp.print(&config, &self); config: config,
file_match: self,
};
cp.print();
} }
} }

View File

@@ -1,42 +1,96 @@
extern crate term; extern crate term;
use super::config::Config; use super::config::Config;
use super::filematch::FileMatch; use super::filematch::*;
pub trait Printer { pub trait Printer {
fn print(&self, config: &Config, file_match: &FileMatch); fn print(&self);
} }
pub struct ColorPrinter; pub struct ColorPrinter<'a> {
pub config: &'a Config,
pub file_match: &'a FileMatch,
}
impl Printer for ColorPrinter { struct SimplePrinter<'a> {
fn print(&self, _config: &Config, mat: &FileMatch) { config: &'a Config,
let mut term = term::stdout().unwrap(); file_match: &'a FileMatch,
term.fg(term::color::YELLOW).unwrap(); }
term.attr(term::Attr::Bold).unwrap();
println!("{}:", mat.file_name);
term.reset().unwrap();
for mat in &mat.matches { impl<'a> Printer for SimplePrinter<'a> {
term.attr(term::Attr::Bold).unwrap(); fn print(&self) {
print!("{}: ", mat.line_number); self.print_file_name();
term.reset().unwrap();
for mat in &self.file_match.matches {
self.print_linenumber(mat);
let mut last_position = 0; let mut last_position = 0;
for (idx, match_index) in mat.match_indexes.iter().enumerate() { for (idx, match_index) in mat.match_indexes.iter().enumerate() {
print!( self.print_first_part_of_line(mat, last_position, match_index.start);
"{}", self.print_match(mat, match_index);
mat.text.get(last_position..match_index.start).unwrap()
);
term.fg(term::color::BRIGHT_RED).unwrap();
print!(
"{}",
mat.text.get(match_index.start..match_index.end).unwrap()
);
term.reset().unwrap();
if idx == mat.match_indexes.len() - 1 { if idx == mat.match_indexes.len() - 1 {
println!("{}", mat.text.get(match_index.end..mat.text.len()).unwrap()); self.print_end_of_line(mat, match_index);
last_position = 0;
} else {
last_position = match_index.end;
}
}
}
println!();
}
}
impl<'a> SimplePrinter<'a> {
fn print_file_name(&self) {
println!("{}:", self.file_match.file_name);
}
fn print_linenumber(&self, mat: &Match) {
print!("{}: ", mat.line_number);
}
fn print_first_part_of_line(&self, mat: &Match, current_position: usize, match_start: usize) {
print!("{}", mat.text.get(current_position..match_start).unwrap());
}
fn print_match(&self, mat: &Match, index: &MatchIndex) {
print!("{}", mat.text.get(index.start..index.end).unwrap());
}
fn print_end_of_line(&self, mat: &Match, index: &MatchIndex) {
println!("{}", mat.text.get(index.end..mat.text.len()).unwrap());
}
}
impl<'a> Printer for ColorPrinter<'a> {
fn print(&self) {
let simple_printer = SimplePrinter {
config: self.config,
file_match: self.file_match,
};
let mut term = term::stdout().unwrap();
term.fg(term::color::YELLOW).unwrap();
term.attr(term::Attr::Bold).unwrap();
simple_printer.print_file_name();
term.reset().unwrap();
for mat in &self.file_match.matches {
term.attr(term::Attr::Bold).unwrap();
simple_printer.print_linenumber(mat);
term.reset().unwrap();
let mut last_position = 0;
for (idx, match_index) in mat.match_indexes.iter().enumerate() {
simple_printer.print_first_part_of_line(mat, last_position, match_index.start);
term.fg(term::color::BRIGHT_RED).unwrap();
simple_printer.print_match(mat, match_index);
term.reset().unwrap();
if idx == mat.match_indexes.len() - 1 {
simple_printer.print_end_of_line(mat, match_index);
last_position = 0; last_position = 0;
} else { } else {
last_position = match_index.end; last_position = match_index.end;