Skip to content

Commit

Permalink
feat: do something with regex (#8)
Browse files Browse the repository at this point in the history
* feat: implement regex search

* write test

* stub out logic

* do it

* some draft

* almost

* this might be it

* do something

* trim
  • Loading branch information
Terkwood authored Jun 9, 2022
1 parent 4828d52 commit 3441c1d
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 3 deletions.
35 changes: 34 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[package]
name = "zeditor"
version = "0.1.0-f"
version = "0.1.0-g"
edition = "2021"

[dependencies]
cursive = { git = "https://github.com/gyscos/cursive" }
regex = "1.5.6"
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod search;
61 changes: 61 additions & 0 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use regex::Regex;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};

#[derive(Debug, PartialEq)]
pub struct FileSearched {
pub path: PathBuf,
pub hits: Vec<Hit>,
}

#[derive(Debug, PartialEq)]
pub struct Hit {
pub search: String,
pub start: usize,
pub end: usize,
pub preview: String,
}

pub fn search(
path: &Path,
terms: &[String],
peek_size: usize,
) -> Result<FileSearched, std::io::Error> {
let mut file = File::open(path)?;
let mut contents = String::new();
let mut hits: Vec<Hit> = vec![];

file.read_to_string(&mut contents)?;

for t in terms {
let re = Regex::new(&format!(r"(\s|^)({})(\s|$)", t)).unwrap();
for hit in re.find_iter(&contents) {
if let Some(subcap) = re.captures(hit.as_str()) {
if let Some(subexact) = subcap.get(2) {
let substart = subexact.start();
let subend = subexact.end() - substart;
println!("hit.end() {}, subend {}", hit.end(), subend);
let start = hit.start() + substart;
let end = start + subend;
hits.push(Hit {
search: t.to_string(),
start,
end,
preview: contents[start.checked_sub(peek_size).unwrap_or_default()
..std::cmp::min(
end.checked_add(peek_size).unwrap_or(contents.len()),
contents.len(),
)]
.to_string(),
})
}
}
}
}

Ok(FileSearched {
path: PathBuf::from(path),
hits,
})
}
7 changes: 7 additions & 0 deletions tests/search.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
scala is a lang

but rust is better

i wrote something in scala today

but then i wrote it in rust
40 changes: 40 additions & 0 deletions tests/search_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use std::path::{Path, PathBuf};
use zeditor::search::*;

#[test]
fn test_search() {
let test_data = format!("{}/tests/search.txt", env!("CARGO_MANIFEST_DIR"));
let path = Path::new(&test_data);
let actual = search(&path, &vec!["scala".to_string(), "rust".to_string()], 3).unwrap();

let expected = FileSearched {
path: PathBuf::from(path),
hits: vec![
Hit {
search: "scala".to_string(),
start: 0,
end: 5,
preview: "scala is".to_string(),
},
Hit {
search: "scala".to_string(),
start: 58,
end: 63,
preview: "in scala to".to_string(),
},
Hit {
search: "rust".to_string(),
start: 21,
end: 25,
preview: "ut rust is".to_string(),
},
Hit {
search: "rust".to_string(),
start: 94,
end: 98,
preview: "in rust".to_string(),
},
],
};
assert_eq!(actual, expected);
}

0 comments on commit 3441c1d

Please sign in to comment.