summaryrefslogtreecommitdiffstats
path: root/grep/examples
diff options
context:
space:
mode:
Diffstat (limited to 'grep/examples')
-rw-r--r--grep/examples/simplegrep.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/grep/examples/simplegrep.rs b/grep/examples/simplegrep.rs
new file mode 100644
index 00000000..fb2d4001
--- /dev/null
+++ b/grep/examples/simplegrep.rs
@@ -0,0 +1,107 @@
+extern crate atty;
+extern crate grep;
+extern crate termcolor;
+extern crate walkdir;
+
+use std::env;
+use std::error;
+use std::ffi::OsString;
+use std::path::Path;
+use std::process;
+use std::result;
+
+use grep::printer::{ColorSpecs, StandardBuilder};
+use grep::regex::RegexMatcher;
+use grep::searcher::{BinaryDetection, SearcherBuilder};
+use termcolor::{ColorChoice, StandardStream};
+use walkdir::WalkDir;
+
+macro_rules! fail {
+ ($($tt:tt)*) => {
+ return Err(From::from(format!($($tt)*)));
+ }
+}
+
+type Result<T> = result::Result<T, Box<error::Error>>;
+
+fn main() {
+ if let Err(err) = try_main() {
+ eprintln!("{}", err);
+ process::exit(1);
+ }
+}
+
+fn try_main() -> Result<()> {
+ let mut args: Vec<OsString> = env::args_os().collect();
+ if args.len() < 2 {
+ fail!("Usage: simplegrep <pattern> [<path> ...]");
+ }
+ if args.len() == 2 {
+ args.push(OsString::from("./"));
+ }
+ let pattern = match args[1].clone().into_string() {
+ Ok(pattern) => pattern,
+ Err(_) => {
+ fail!(
+ "pattern is not valid UTF-8: '{:?}'",
+ args[1].to_string_lossy()
+ );
+ }
+ };
+ search(&pattern, &args[2..])
+}
+
+fn search(pattern: &str, paths: &[OsString]) -> Result<()> {
+ let matcher = RegexMatcher::new_line_matcher(&pattern)?;
+ let mut searcher = SearcherBuilder::new()
+ .binary_detection(BinaryDetection::quit(b'\x00'))
+ .build();
+ let mut printer = StandardBuilder::new()
+ .color_specs(colors())
+ .build(StandardStream::stdout(color_choice()));
+
+ for path in paths {
+ for result in WalkDir::new(path) {
+ let dent = match result {
+ Ok(dent) => dent,
+ Err(err) => {
+ eprintln!(
+ "{}: {}",
+ err.path().unwrap_or(Path::new("error")).display(),
+ err,
+ );
+ continue;
+ }
+ };
+ if !dent.file_type().is_file() {
+ continue;
+ }
+ let result = searcher.search_path(
+ &matcher,
+ dent.path(),
+ printer.sink_with_path(&matcher, dent.path()),
+ );
+ if let Err(err) = result {
+ eprintln!("{}: {}", dent.path().display(), err);
+ }
+ }
+ }
+ Ok(())
+}
+
+fn color_choice() -> ColorChoice {
+ if atty::is(atty::Stream::Stdout) {
+ ColorChoice::Auto
+ } else {
+ ColorChoice::Never
+ }
+}
+
+fn colors() -> ColorSpecs {
+ ColorSpecs::new(&[
+ "path:fg:magenta".parse().unwrap(),
+ "line:fg:green".parse().unwrap(),
+ "match:fg:red".parse().unwrap(),
+ "match:style:bold".parse().unwrap(),
+ ])
+}