use crate::Result;
pub fn full_keyword(query: &str, keywords: &[impl AsRef<str>]) -> String {
let query_words_len = query.split_whitespace().count();
let min_phrase_words_len = if query.ends_with(char::is_whitespace) {
query_words_len + 1
} else {
query_words_len
};
keywords
.iter()
.map(AsRef::as_ref)
.filter(|phrase| phrase.starts_with(query))
.map(|phrase| phrase.split_whitespace().collect::<Vec<_>>())
.find(|phrase_words| phrase_words.len() > min_phrase_words_len)
.map(|phrase_words| phrase_words[..min_phrase_words_len].join(" "))
.unwrap_or_else(|| {
keywords
.iter()
.map(AsRef::as_ref)
.filter(|phrase| phrase.starts_with(query) && query.len() < phrase.len())
.max_by_key(|phrase| phrase.trim().len())
.unwrap_or(query)
.to_owned()
})
}
pub fn filter_map_chunks<T: Clone>(
words: &[&str],
max_chunk_size: usize,
f: impl Fn(&str, usize, &[T]) -> Result<Option<Vec<T>>>,
) -> Result<Vec<Vec<T>>> {
let normalized_query = words.join(" ");
filter_map_chunks_recurse(words, &normalized_query, &mut vec![], 0, max_chunk_size, &f)
}
fn filter_map_chunks_recurse<T: Clone>(
remaining_words: &[&str],
remaining_query: &str,
path: &mut Vec<T>,
chunk_index: usize,
max_chunk_size: usize,
f: &impl Fn(&str, usize, &[T]) -> Result<Option<Vec<T>>>,
) -> Result<Vec<Vec<T>>> {
let mut this_step_paths: Vec<Vec<T>> = vec![];
for chunk_size in 1..=max_chunk_size {
if remaining_words.len() < chunk_size {
break;
}
let chunk_char_len = remaining_words[..chunk_size]
.iter()
.fold(chunk_size - 1, |memo, w| memo + w.len());
let chunk = &remaining_query[..chunk_char_len];
if let Some(mapped_values) = f(chunk, chunk_index, &path[..])? {
for value in mapped_values {
if chunk_size == remaining_words.len() {
this_step_paths.push(vec![value.clone()]);
} else {
path.push(value.clone());
let subtree_paths = filter_map_chunks_recurse(
&remaining_words[chunk_size..],
&remaining_query[(chunk_char_len + 1)..],
path,
chunk_index + chunk_size,
max_chunk_size,
f,
)?;
path.pop();
for mut p in subtree_paths {
p.insert(0, value.clone());
this_step_paths.push(p);
}
}
}
}
}
Ok(this_step_paths)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn keywords_with_more_words() {
assert_eq!(
full_keyword(
"moz",
&[
"moz",
"mozi",
"mozil",
"mozill",
"mozilla",
"mozilla firefox"
]
),
"mozilla".to_owned(),
);
assert_eq!(
full_keyword(
"mozilla",
&[
"moz",
"mozi",
"mozil",
"mozill",
"mozilla",
"mozilla firefox"
]
),
"mozilla".to_owned(),
);
}
#[test]
fn keywords_with_longer_phrase() {
assert_eq!(
full_keyword("moz", &["moz", "mozi", "mozil", "mozill", "mozilla"]),
"mozilla".to_owned()
);
assert_eq!(
full_keyword(
"mozilla f",
&["moz", "mozi", "mozil", "mozill", "mozilla firefox"]
),
"mozilla firefox".to_owned()
);
}
#[test]
fn query_ends_with_space() {
assert_eq!(
full_keyword(
"mozilla ",
&["moz", "mozi", "mozil", "mozill", "mozilla firefox"]
),
"mozilla firefox".to_owned()
);
}
fn fmc<T: Clone>(
query: &str,
max_chunk_size: usize,
f: impl Fn(&str, usize, &[T]) -> Result<Option<Vec<T>>>,
) -> Result<Vec<Vec<T>>> {
let words: Vec<_> = query.split_whitespace().collect();
filter_map_chunks(&words, max_chunk_size, f)
}
fn check_paths(actual: Vec<Vec<(String, usize)>>, expected: Vec<Vec<(&str, usize)>>) {
assert_eq!(
actual,
expected
.into_iter()
.map(|p| p
.into_iter()
.map(|(w, i)| (w.to_string(), i))
.collect::<Vec<_>>())
.collect::<Vec<Vec<_>>>()
);
}
#[test]
fn filter_map_chunks_1() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)]],
);
Ok(())
}
#[test]
fn filter_map_chunks_2() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_5() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 5, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
vec![("a b c d e", 0)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_1_map_many() -> anyhow::Result<()> {
let paths = fmc("a b c", 1, |chunk, _, _| {
Ok(Some((0..3).map(|i| format!("{chunk}{i}")).collect()))
})?;
assert_eq!(
paths,
vec![
vec!["a0", "b0", "c0"],
vec!["a0", "b0", "c1"],
vec!["a0", "b0", "c2"],
vec!["a0", "b1", "c0"],
vec!["a0", "b1", "c1"],
vec!["a0", "b1", "c2"],
vec!["a0", "b2", "c0"],
vec!["a0", "b2", "c1"],
vec!["a0", "b2", "c2"],
vec!["a1", "b0", "c0"],
vec!["a1", "b0", "c1"],
vec!["a1", "b0", "c2"],
vec!["a1", "b1", "c0"],
vec!["a1", "b1", "c1"],
vec!["a1", "b1", "c2"],
vec!["a1", "b2", "c0"],
vec!["a1", "b2", "c1"],
vec!["a1", "b2", "c2"],
vec!["a2", "b0", "c0"],
vec!["a2", "b0", "c1"],
vec!["a2", "b0", "c2"],
vec!["a2", "b1", "c0"],
vec!["a2", "b1", "c1"],
vec!["a2", "b1", "c2"],
vec!["a2", "b2", "c0"],
vec!["a2", "b2", "c1"],
vec!["a2", "b2", "c2"]
]
);
Ok(())
}
#[test]
fn filter_map_chunks_2_map_many() -> anyhow::Result<()> {
let paths = fmc("a b c", 2, |chunk, _, _| {
Ok(Some((0..3).map(|i| format!("{chunk}{i}")).collect()))
})?;
assert_eq!(
paths,
vec![
vec!["a0", "b0", "c0"],
vec!["a0", "b0", "c1"],
vec!["a0", "b0", "c2"],
vec!["a0", "b1", "c0"],
vec!["a0", "b1", "c1"],
vec!["a0", "b1", "c2"],
vec!["a0", "b2", "c0"],
vec!["a0", "b2", "c1"],
vec!["a0", "b2", "c2"],
vec!["a0", "b c0"],
vec!["a0", "b c1"],
vec!["a0", "b c2"],
vec!["a1", "b0", "c0"],
vec!["a1", "b0", "c1"],
vec!["a1", "b0", "c2"],
vec!["a1", "b1", "c0"],
vec!["a1", "b1", "c1"],
vec!["a1", "b1", "c2"],
vec!["a1", "b2", "c0"],
vec!["a1", "b2", "c1"],
vec!["a1", "b2", "c2"],
vec!["a1", "b c0"],
vec!["a1", "b c1"],
vec!["a1", "b c2"],
vec!["a2", "b0", "c0"],
vec!["a2", "b0", "c1"],
vec!["a2", "b0", "c2"],
vec!["a2", "b1", "c0"],
vec!["a2", "b1", "c1"],
vec!["a2", "b1", "c2"],
vec!["a2", "b2", "c0"],
vec!["a2", "b2", "c1"],
vec!["a2", "b2", "c2"],
vec!["a2", "b c0"],
vec!["a2", "b c1"],
vec!["a2", "b c2"],
vec!["a b0", "c0"],
vec!["a b0", "c1"],
vec!["a b0", "c2"],
vec!["a b1", "c0"],
vec!["a b1", "c1"],
vec!["a b1", "c2"],
vec!["a b2", "c0"],
vec!["a b2", "c1"],
vec!["a b2", "c2"]
]
);
Ok(())
}
#[test]
fn filter_map_chunks_1_prune_a() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| match chunk {
"a" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(paths, vec![]);
Ok(())
}
#[test]
fn filter_map_chunks_1_prune_b() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| match chunk {
"b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(paths, vec![]);
Ok(())
}
#[test]
fn filter_map_chunks_1_prune_c() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| match chunk {
"c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(paths, vec![]);
Ok(())
}
#[test]
fn filter_map_chunks_1_prune_d() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| match chunk {
"d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(paths, vec![]);
Ok(())
}
#[test]
fn filter_map_chunks_1_prune_e() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 1, |chunk, chunk_index, _| match chunk {
"e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(paths, vec![]);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_a() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"a" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_b() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_c() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_d() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_e() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_ab() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"a b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_bc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_cd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_de() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_a_bc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"a" | "b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_a_cd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"a" | "c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_bc_cd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"b c" | "c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_2_prune_bc_de() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 2, |chunk, chunk_index, _| match chunk {
"b c" | "d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_a() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"a" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_b() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_c() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_d() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_e() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_ab() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"a b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_bc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_cd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_de() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_abc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"a b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_bcd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"b c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_cde() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"c d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_3_prune_a_bc_cde() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 3, |chunk, chunk_index, _| match chunk {
"a" | "b c" | "c d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_a() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_b() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_c() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_d() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_e() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_ab() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a b" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_bc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_cd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_de() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_abc() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a b c" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_bcd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"b c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_cde() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"c d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_abcd() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a b c d" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a", 0), ("b c d e", 1)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_bcde() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"b c d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b", 1), ("c d e", 2)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a", 0), ("b c d", 1), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_a_bc_de() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a" | "b c" | "d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b", 0), ("c d e", 2)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_4_prune_a_bc_cde() -> anyhow::Result<()> {
let paths = fmc("a b c d e", 4, |chunk, chunk_index, _| match chunk {
"a" | "b c" | "c d e" => Ok(None),
_ => Ok(Some(vec![(chunk.to_string(), chunk_index)])),
})?;
check_paths(
paths,
vec![
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
vec![("a b c", 0), ("d", 3), ("e", 4)],
vec![("a b c", 0), ("d e", 3)],
vec![("a b c d", 0), ("e", 4)],
],
);
Ok(())
}
#[test]
fn filter_map_chunks_spaces() -> anyhow::Result<()> {
let paths = fmc(" a b c d e ", 2, |chunk, chunk_index, _| {
Ok(Some(vec![(chunk.to_string(), chunk_index)]))
})?;
check_paths(
paths,
vec![
vec![("a", 0), ("b", 1), ("c", 2), ("d", 3), ("e", 4)],
vec![("a", 0), ("b", 1), ("c", 2), ("d e", 3)],
vec![("a", 0), ("b", 1), ("c d", 2), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d", 3), ("e", 4)],
vec![("a", 0), ("b c", 1), ("d e", 3)],
vec![("a b", 0), ("c", 2), ("d", 3), ("e", 4)],
vec![("a b", 0), ("c", 2), ("d e", 3)],
vec![("a b", 0), ("c d", 2), ("e", 4)],
],
);
Ok(())
}
}