mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-01-19 05:49:14 +02:00
bb110c1ebe
This commit does the work to delete the old `grep` crate and effectively rewrite most of ripgrep core to use the new libripgrep crates. The new `grep` crate is now a facade that collects the various crates that make up libripgrep. The most complex part of ripgrep core is now arguably the translation between command line parameters and the library options, which is ultimately where we want to be.
88 lines
2.2 KiB
Rust
88 lines
2.2 KiB
Rust
extern crate crossbeam;
|
|
extern crate ignore;
|
|
extern crate walkdir;
|
|
|
|
use std::env;
|
|
use std::io::{self, Write};
|
|
use std::path::Path;
|
|
use std::sync::Arc;
|
|
use std::thread;
|
|
|
|
use crossbeam::sync::MsQueue;
|
|
use ignore::WalkBuilder;
|
|
use walkdir::WalkDir;
|
|
|
|
fn main() {
|
|
let mut path = env::args().nth(1).unwrap();
|
|
let mut parallel = false;
|
|
let mut simple = false;
|
|
let queue: Arc<MsQueue<Option<DirEntry>>> = Arc::new(MsQueue::new());
|
|
if path == "parallel" {
|
|
path = env::args().nth(2).unwrap();
|
|
parallel = true;
|
|
} else if path == "walkdir" {
|
|
path = env::args().nth(2).unwrap();
|
|
simple = true;
|
|
}
|
|
|
|
let stdout_queue = queue.clone();
|
|
let stdout_thread = thread::spawn(move || {
|
|
let mut stdout = io::BufWriter::new(io::stdout());
|
|
while let Some(dent) = stdout_queue.pop() {
|
|
write_path(&mut stdout, dent.path());
|
|
}
|
|
});
|
|
|
|
if parallel {
|
|
let walker = WalkBuilder::new(path).threads(6).build_parallel();
|
|
walker.run(|| {
|
|
let queue = queue.clone();
|
|
Box::new(move |result| {
|
|
use ignore::WalkState::*;
|
|
|
|
queue.push(Some(DirEntry::Y(result.unwrap())));
|
|
Continue
|
|
})
|
|
});
|
|
} else if simple {
|
|
let walker = WalkDir::new(path);
|
|
for result in walker {
|
|
queue.push(Some(DirEntry::X(result.unwrap())));
|
|
}
|
|
} else {
|
|
let walker = WalkBuilder::new(path).build();
|
|
for result in walker {
|
|
queue.push(Some(DirEntry::Y(result.unwrap())));
|
|
}
|
|
}
|
|
queue.push(None);
|
|
stdout_thread.join().unwrap();
|
|
}
|
|
|
|
enum DirEntry {
|
|
X(walkdir::DirEntry),
|
|
Y(ignore::DirEntry),
|
|
}
|
|
|
|
impl DirEntry {
|
|
fn path(&self) -> &Path {
|
|
match *self {
|
|
DirEntry::X(ref x) => x.path(),
|
|
DirEntry::Y(ref y) => y.path(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(unix)]
|
|
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
|
use std::os::unix::ffi::OsStrExt;
|
|
wtr.write(path.as_os_str().as_bytes()).unwrap();
|
|
wtr.write(b"\n").unwrap();
|
|
}
|
|
|
|
#[cfg(not(unix))]
|
|
fn write_path<W: Write>(mut wtr: W, path: &Path) {
|
|
wtr.write(path.to_string_lossy().as_bytes()).unwrap();
|
|
wtr.write(b"\n").unwrap();
|
|
}
|