mod fields;
mod filter;
mod fuzzy;
mod normalize;
mod options;
mod substring;
#[cfg(test)]
mod test_support;
pub use filter::filter_tasks;
pub use fuzzy::fuzzy_search_tasks;
pub use options::SearchOptions;
pub use substring::search_tasks;
use crate::contracts::Task;
use anyhow::Result;
pub fn search_tasks_with_options<'a>(
tasks: impl IntoIterator<Item = &'a Task>,
query: &str,
options: &SearchOptions,
) -> Result<Vec<&'a Task>> {
if options.use_fuzzy {
fuzzy_search_tasks(tasks, query, options.case_sensitive)
.map(|results| results.into_iter().map(|(_, task)| task).collect())
} else {
search_tasks(tasks, query, options.use_regex, options.case_sensitive)
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_support::task;
#[test]
fn search_tasks_with_options_fuzzy_mode() -> Result<()> {
let mut t1 = task("RQ-0001");
t1.title = "Fix authentication".to_string();
let mut t2 = task("RQ-0002");
t2.title = "Update docs".to_string();
let tasks: Vec<&Task> = vec![&t1, &t2];
let options = SearchOptions {
use_regex: false,
case_sensitive: false,
use_fuzzy: true,
scopes: vec![],
};
let results = search_tasks_with_options(tasks.iter().copied(), "auth", &options)?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].id, "RQ-0001");
Ok(())
}
#[test]
fn search_tasks_with_options_regex_mode() -> Result<()> {
let mut t1 = task("RQ-0001");
t1.title = "Fix RQ-1234 bug".to_string();
let mut t2 = task("RQ-0002");
t2.title = "Update docs".to_string();
let tasks: Vec<&Task> = vec![&t1, &t2];
let options = SearchOptions {
use_regex: true,
case_sensitive: false,
use_fuzzy: false,
scopes: vec![],
};
let results = search_tasks_with_options(tasks.iter().copied(), r"RQ-\d{4}", &options)?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].id, "RQ-0001");
Ok(())
}
#[test]
fn search_tasks_with_options_substring_mode() -> Result<()> {
let mut t1 = task("RQ-0001");
t1.title = "Fix authentication".to_string();
let mut t2 = task("RQ-0002");
t2.title = "Update docs".to_string();
let tasks: Vec<&Task> = vec![&t1, &t2];
let options = SearchOptions {
use_regex: false,
case_sensitive: false,
use_fuzzy: false,
scopes: vec![],
};
let results = search_tasks_with_options(tasks.iter().copied(), "auth", &options)?;
assert_eq!(results.len(), 1);
assert_eq!(results[0].id, "RQ-0001");
Ok(())
}
}