Skip to content

Commit

Permalink
fzf: add Fzf trait
Browse files Browse the repository at this point in the history
  • Loading branch information
noib3 committed Nov 23, 2023
1 parent fbf0c6b commit b049092
Show file tree
Hide file tree
Showing 7 changed files with 339 additions and 363 deletions.
294 changes: 193 additions & 101 deletions src/algos/fzf/common.rs → src/algos/fzf/fzf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,98 @@ use core::ops::Range;
use super::{query::*, *};
use crate::*;

/// TODO: docs
pub(super) trait Fzf {
/// TODO: docs
fn alloc_chars<'a>(&mut self, candidate: &str) -> &'a [char];

/// TODO: docs
fn scheme(&self) -> &Scheme;

/// TODO: docs
fn fuzzy<const RANGES: bool>(
&mut self,
pattern: Pattern,
candidate: Candidate,
ranges: &mut MatchedRanges,
) -> Option<Score>;

/// TODO: docs
fn score<const RANGES: bool>(
&mut self,
pattern: Pattern,
candidate: Candidate,
ranges: &mut MatchedRanges,
) -> Option<Score> {
let score = match pattern.match_type {
MatchType::Fuzzy => {
if pattern.is_inverse {
self.fuzzy::<false>(pattern, candidate, ranges)
} else {
self.fuzzy::<RANGES>(pattern, candidate, ranges)
}
},

MatchType::Exact => {
todo!();
},

MatchType::PrefixExact => {
todo!();
},

MatchType::SuffixExact => {
todo!();
},

MatchType::EqualExact => {
todo!();
},
};

match (score.is_some(), pattern.is_inverse) {
(true, false) => score,
(false, true) => Some(0),
_ => None,
}
}

/// TODO: docs
#[inline(always)]
fn distance<const RANGES: bool>(
&mut self,
query: FzfQuery,
candidate: &str,
ranges: &mut MatchedRanges,
) -> Option<FzfDistance> {
if query.is_empty() {
return Some(FzfDistance::from_score(0));
}

let candidate = if candidate.is_ascii() {
Candidate::Ascii(candidate.as_bytes())
} else {
Candidate::Unicode(self.alloc_chars(candidate))
};

match query.search_mode {
SearchMode::NotExtended(pattern) => self
.fuzzy::<RANGES>(pattern, candidate, ranges)
.map(FzfDistance::from_score),

SearchMode::Extended(conditions) => {
let mut total_score: Score = 0;
for condition in conditions {
total_score += condition.iter().find_map(|pattern| {
self.score::<RANGES>(pattern, candidate, ranges)
})?;
}
Some(FzfDistance::from_score(total_score))
},
}
}
}

/// TODO: docs
#[inline]
pub(super) fn calculate_score(
Expand Down Expand Up @@ -406,104 +498,104 @@ fn ignored_candidate_trailing_spaces(
}
}

#[cfg(test)]
mod tests {
#![allow(clippy::single_range_in_vec_init)]

use super::*;

#[test]
fn equal_match_1() {
let pattern =
Pattern::parse("^AbC$".chars().collect::<Vec<_>>().leak());

let mut ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
"ABC",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_none());

{
ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
"AbC",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_some());

assert_eq!(ranges_buf.as_slice(), [0..3]);
}

{
ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
"AbC ",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_some());

assert_eq!(ranges_buf.as_slice(), [0..3]);
}

{
ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
" AbC ",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_some());

assert_eq!(ranges_buf.as_slice(), [1..4]);
}

{
ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
" AbC",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_some());

assert_eq!(ranges_buf.as_slice(), [2..5]);
}
}

#[test]
fn exact_match_1() {
let pattern = Pattern::parse("abc".chars().collect::<Vec<_>>().leak());

let mut ranges_buf = MatchedRanges::default();

assert!(exact_match(
pattern,
"aabbcc abc",
AsciiCandidateOpts::new(true),
&Scheme::default(),
Some(&mut ranges_buf)
)
.is_some());

assert_eq!(ranges_buf.as_slice(), [7..10]);
}
}
// #[cfg(test)]
// mod tests {
// #![allow(clippy::single_range_in_vec_init)]
//
// use super::*;
//
// #[test]
// fn equal_match_1() {
// let pattern =
// Pattern::parse("^AbC$".chars().collect::<Vec<_>>().leak());
//
// let mut ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// "ABC",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_none());
//
// {
// ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// "AbC",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_some());
//
// assert_eq!(ranges_buf.as_slice(), [0..3]);
// }
//
// {
// ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// "AbC ",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_some());
//
// assert_eq!(ranges_buf.as_slice(), [0..3]);
// }
//
// {
// ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// " AbC ",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_some());
//
// assert_eq!(ranges_buf.as_slice(), [1..4]);
// }
//
// {
// ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// " AbC",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_some());
//
// assert_eq!(ranges_buf.as_slice(), [2..5]);
// }
// }
//
// #[test]
// fn exact_match_1() {
// let pattern = Pattern::parse("abc".chars().collect::<Vec<_>>().leak());
//
// let mut ranges_buf = MatchedRanges::default();
//
// assert!(exact_match(
// pattern,
// "aabbcc abc",
// todo!(),
// &Scheme::default(),
// Some(&mut ranges_buf)
// )
// .is_some());
//
// assert_eq!(ranges_buf.as_slice(), [7..10]);
// }
// }
Loading

0 comments on commit b049092

Please sign in to comment.