1 use std::env;
2 use std::error::Error;
3 use std::ffi::OsString;
4 use std::process;
5
6 use grep::cli;
7 use grep::printer::{ColorSpecs, StandardBuilder};
8 use grep::regex::RegexMatcher;
9 use grep::searcher::{BinaryDetection, SearcherBuilder};
10 use termcolor::ColorChoice;
11 use walkdir::WalkDir;
12
main()13 fn main() {
14 if let Err(err) = try_main() {
15 eprintln!("{}", err);
16 process::exit(1);
17 }
18 }
19
try_main() -> Result<(), Box<dyn Error>>20 fn try_main() -> Result<(), Box<dyn Error>> {
21 let mut args: Vec<OsString> = env::args_os().collect();
22 if args.len() < 2 {
23 return Err("Usage: simplegrep <pattern> [<path> ...]".into());
24 }
25 if args.len() == 2 {
26 args.push(OsString::from("./"));
27 }
28 search(cli::pattern_from_os(&args[1])?, &args[2..])
29 }
30
search(pattern: &str, paths: &[OsString]) -> Result<(), Box<dyn Error>>31 fn search(pattern: &str, paths: &[OsString]) -> Result<(), Box<dyn Error>> {
32 let matcher = RegexMatcher::new_line_matcher(&pattern)?;
33 let mut searcher = SearcherBuilder::new()
34 .binary_detection(BinaryDetection::quit(b'\x00'))
35 .line_number(false)
36 .build();
37 let mut printer = StandardBuilder::new()
38 .color_specs(ColorSpecs::default_with_color())
39 .build(cli::stdout(if cli::is_tty_stdout() {
40 ColorChoice::Auto
41 } else {
42 ColorChoice::Never
43 }));
44
45 for path in paths {
46 for result in WalkDir::new(path) {
47 let dent = match result {
48 Ok(dent) => dent,
49 Err(err) => {
50 eprintln!("{}", err);
51 continue;
52 }
53 };
54 if !dent.file_type().is_file() {
55 continue;
56 }
57 let result = searcher.search_path(
58 &matcher,
59 dent.path(),
60 printer.sink_with_path(&matcher, dent.path()),
61 );
62 if let Err(err) = result {
63 eprintln!("{}: {}", dent.path().display(), err);
64 }
65 }
66 }
67 Ok(())
68 }
69