Add search feature using grep.
This commit is contained in:
53
src/lib.rs
53
src/lib.rs
@@ -10,6 +10,7 @@ extern crate git2;
|
||||
extern crate regex;
|
||||
extern crate pathdiff;
|
||||
extern crate chrono;
|
||||
extern crate grep;
|
||||
#[macro_use] extern crate toml;
|
||||
|
||||
use std::fs;
|
||||
@@ -724,3 +725,55 @@ impl<'a> Linker<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Searcher<'a> {
|
||||
historian: &'a Historian
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SearchResult {
|
||||
pub page: Page,
|
||||
pub matches: Vec<String>
|
||||
}
|
||||
|
||||
impl<'a> Searcher<'a> {
|
||||
pub fn new(historian: &Historian) -> Searcher {
|
||||
Searcher {
|
||||
historian
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search(&self, root: &Page, query: &str) -> Vec<SearchResult> {
|
||||
let mut searcher = grep::searcher::SearcherBuilder::new().build();
|
||||
let matcher = grep::regex::RegexMatcherBuilder::new()
|
||||
.fixed_strings(true)
|
||||
.case_insensitive(true)
|
||||
.build(query)
|
||||
.unwrap();
|
||||
|
||||
let mut results: Vec<SearchResult> = vec![];
|
||||
self.do_search(root, &mut results, &mut searcher, &matcher);
|
||||
results
|
||||
}
|
||||
|
||||
fn do_search(&self, root: &Page, results: &mut Vec<SearchResult>, searcher: &mut grep::searcher::Searcher, matcher: &grep::regex::RegexMatcher) {
|
||||
for child in &root.children {
|
||||
if let Some(child_page) = self.historian.resolve_to_page(&child.full_name) {
|
||||
let mut matches: Vec<String> = vec![];
|
||||
searcher.search_path(matcher, &child.path, grep::searcher::sinks::UTF8(|lnum, line| {
|
||||
matches.push(line.to_owned());
|
||||
Ok(true)
|
||||
}));
|
||||
|
||||
self.do_search(&child_page, results, searcher, matcher);
|
||||
|
||||
if !matches.is_empty() {
|
||||
results.push(SearchResult {
|
||||
page: child_page,
|
||||
matches
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user