Organize code into separate files
This commit is contained in:
28
src/filematch.rs
Normal file
28
src/filematch.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use super::config::Config;
|
||||
use super::printer::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FileMatch {
|
||||
pub file_name: String,
|
||||
pub matches: Vec<Match>,
|
||||
}
|
||||
|
||||
impl FileMatch {
|
||||
pub fn print(&self, config: &Config) {
|
||||
let cp = ColorPrinter {};
|
||||
cp.print(&config, &self);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Match {
|
||||
pub line_number: usize,
|
||||
pub match_indexes: Vec<MatchIndex>,
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MatchIndex {
|
||||
pub start: usize,
|
||||
pub end: usize,
|
||||
}
|
||||
3
src/lib.rs
Normal file
3
src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub mod config;
|
||||
pub mod filematch;
|
||||
pub mod printer;
|
||||
75
src/main.rs
75
src/main.rs
@@ -1,3 +1,5 @@
|
||||
use rack::config::Config;
|
||||
use rack::filematch::*;
|
||||
use std::fs::{self, File};
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
@@ -5,10 +7,8 @@ use std::path::Path;
|
||||
|
||||
extern crate term;
|
||||
|
||||
mod config;
|
||||
|
||||
fn main() {
|
||||
let config = config::Config::from_args();
|
||||
let config = Config::from_args();
|
||||
|
||||
let search_path = &config.path;
|
||||
let path = match search_path.starts_with('/') {
|
||||
@@ -22,15 +22,15 @@ fn main() {
|
||||
let results = traverse_dir(&config, path, |config, path| check_file(config, path));
|
||||
match results {
|
||||
Result::Ok(matches) if matches.len() == 0 => println!("No matches :("),
|
||||
Result::Ok(matches) => print_report(&matches),
|
||||
Result::Ok(matches) => print_report(&config, &matches),
|
||||
Result::Err(msg) => println!("Error while parsing: {}", msg),
|
||||
}
|
||||
}
|
||||
|
||||
fn traverse_dir(
|
||||
config: &config::Config,
|
||||
config: &Config,
|
||||
dir: &Path,
|
||||
operation: fn(&config::Config, &Path) -> io::Result<FileMatch>,
|
||||
operation: fn(&Config, &Path) -> io::Result<FileMatch>,
|
||||
) -> io::Result<Vec<FileMatch>> {
|
||||
let mut matches: Vec<FileMatch> = Vec::new();
|
||||
for entry in fs::read_dir(dir)? {
|
||||
@@ -60,64 +60,7 @@ fn traverse_dir(
|
||||
Ok(matches)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FileMatch {
|
||||
file_name: String,
|
||||
matches: Vec<Match>,
|
||||
}
|
||||
|
||||
impl FileMatch {
|
||||
fn print(&self) {
|
||||
let mut term = term::stdout().unwrap();
|
||||
term.fg(term::color::YELLOW).unwrap();
|
||||
term.attr(term::Attr::Bold).unwrap();
|
||||
println!("{}:", self.file_name);
|
||||
term.reset().unwrap();
|
||||
|
||||
for mat in &self.matches {
|
||||
term.attr(term::Attr::Bold).unwrap();
|
||||
print!("{}: ", mat.line_number);
|
||||
term.reset().unwrap();
|
||||
|
||||
let mut last_position = 0;
|
||||
for (idx, match_index) in mat.match_indexes.iter().enumerate() {
|
||||
print!(
|
||||
"{}",
|
||||
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 {
|
||||
println!("{}", mat.text.get(match_index.end..mat.text.len()).unwrap());
|
||||
last_position = 0;
|
||||
} else {
|
||||
last_position = match_index.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Match {
|
||||
line_number: usize,
|
||||
match_indexes: Vec<MatchIndex>,
|
||||
text: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct MatchIndex {
|
||||
start: usize,
|
||||
end: usize,
|
||||
}
|
||||
|
||||
fn check_file(config: &config::Config, path: &Path) -> io::Result<FileMatch> {
|
||||
fn check_file(config: &Config, path: &Path) -> io::Result<FileMatch> {
|
||||
let mut pattern = config.pattern.clone();
|
||||
|
||||
let file = File::open(&path)?;
|
||||
@@ -155,8 +98,8 @@ fn check_file(config: &config::Config, path: &Path) -> io::Result<FileMatch> {
|
||||
})
|
||||
}
|
||||
|
||||
fn print_report(matches: &Vec<FileMatch>) {
|
||||
fn print_report(config: &Config, matches: &Vec<FileMatch>) {
|
||||
for file in matches {
|
||||
file.print()
|
||||
file.print(config)
|
||||
}
|
||||
}
|
||||
|
||||
48
src/printer.rs
Normal file
48
src/printer.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
extern crate term;
|
||||
|
||||
use super::config::Config;
|
||||
use super::filematch::FileMatch;
|
||||
|
||||
pub trait Printer {
|
||||
fn print(&self, config: &Config, file_match: &FileMatch);
|
||||
}
|
||||
|
||||
pub struct ColorPrinter;
|
||||
|
||||
impl Printer for ColorPrinter {
|
||||
fn print(&self, _config: &Config, mat: &FileMatch) {
|
||||
let mut term = term::stdout().unwrap();
|
||||
term.fg(term::color::YELLOW).unwrap();
|
||||
term.attr(term::Attr::Bold).unwrap();
|
||||
println!("{}:", mat.file_name);
|
||||
term.reset().unwrap();
|
||||
|
||||
for mat in &mat.matches {
|
||||
term.attr(term::Attr::Bold).unwrap();
|
||||
print!("{}: ", mat.line_number);
|
||||
term.reset().unwrap();
|
||||
|
||||
let mut last_position = 0;
|
||||
for (idx, match_index) in mat.match_indexes.iter().enumerate() {
|
||||
print!(
|
||||
"{}",
|
||||
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 {
|
||||
println!("{}", mat.text.get(match_index.end..mat.text.len()).unwrap());
|
||||
last_position = 0;
|
||||
} else {
|
||||
last_position = match_index.end;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user