1mod matcher;
2mod paths;
3mod strings;
4
5pub use paths::{
6 PathMatch, PathMatchCandidate, PathMatchCandidateSet, match_fixed_path_set, match_path_sets,
7};
8pub use strings::{StringMatch, StringMatchCandidate, match_strings, match_strings_async};
9
10pub(crate) struct Cancelled;
11
12#[derive(Copy, Clone, Debug, PartialEq, Eq)]
13pub enum Case {
14 Smart,
15 Ignore,
16}
17
18impl Case {
19 pub fn smart_if_uppercase_in(query: &str) -> Self {
20 if query.chars().any(|c| c.is_uppercase()) {
21 Self::Smart
22 } else {
23 Self::Ignore
24 }
25 }
26
27 pub fn is_smart(self) -> bool {
28 matches!(self, Self::Smart)
29 }
30}
31
32#[derive(Copy, Clone, Debug, PartialEq, Eq)]
33pub enum LengthPenalty {
34 On,
35 Off,
36}
37
38impl LengthPenalty {
39 pub fn from_bool(on: bool) -> Self {
40 if on { Self::On } else { Self::Off }
41 }
42
43 pub fn is_on(self) -> bool {
44 matches!(self, Self::On)
45 }
46}
47
48/// Reconstruct byte-offset match positions from a list of matched char offsets
49/// that is already sorted ascending and deduplicated.
50pub(crate) fn positions_from_sorted(s: &str, sorted_char_indices: &[u32]) -> Vec<usize> {
51 let mut iter = sorted_char_indices.iter().copied().peekable();
52 let mut out = Vec::with_capacity(sorted_char_indices.len());
53 for (char_offset, (byte_offset, _)) in s.char_indices().enumerate() {
54 if iter.peek().is_none() {
55 break;
56 }
57 if iter.next_if(|&m| m == char_offset as u32).is_some() {
58 out.push(byte_offset);
59 }
60 }
61 out
62}