Skip to main content

yuru_core/
config.rs

1/// Search and ranking configuration used by index and query execution.
2#[derive(Clone, Debug)]
3pub struct SearchConfig {
4    /// Maximum number of expanded query variants kept for one query.
5    pub max_query_variants: usize,
6    /// Maximum number of search keys kept for one candidate.
7    pub max_search_keys_per_candidate: usize,
8    /// Maximum total UTF-8 bytes for non-base search keys on one candidate.
9    pub max_total_key_bytes_per_candidate: usize,
10    /// Maximum number of results returned after ranking.
11    pub limit: usize,
12    /// Number of top candidates to rescore for quality-oriented ordering.
13    pub top_b_for_quality_score: usize,
14    /// Uses exact substring scoring instead of fuzzy subsequence scoring.
15    pub exact: bool,
16    /// Enables fzf-style extended query syntax.
17    pub extended: bool,
18    /// Preserves case during matching when true.
19    pub case_sensitive: bool,
20    /// Disables filtering and returns candidates in ranking order only.
21    pub disabled: bool,
22    /// Keeps input order instead of sorting by score.
23    pub no_sort: bool,
24    /// Adds normalized candidate and query keys.
25    pub normalize: bool,
26    /// Fuzzy matcher implementation used for scoring.
27    pub matcher_algo: MatcherAlgo,
28    /// Ordered tiebreak rules applied after score comparison.
29    pub tiebreaks: Vec<Tiebreak>,
30}
31
32/// Candidate-key generation budget passed to language backends.
33#[derive(Clone, Copy, Debug, Eq, PartialEq)]
34pub struct KeyBudget {
35    /// Maximum number of generated search keys to produce for one candidate.
36    pub max_keys: usize,
37}
38
39/// Query-variant generation budget passed to language backends.
40#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub struct QueryBudget {
42    /// Maximum number of query variants to produce for one query.
43    pub max_variants: usize,
44}
45
46impl SearchConfig {
47    /// Returns the candidate-key generation budget represented by this config.
48    pub fn key_budget(&self) -> KeyBudget {
49        KeyBudget {
50            max_keys: self.max_search_keys_per_candidate,
51        }
52    }
53
54    /// Returns the query-variant generation budget represented by this config.
55    pub fn query_budget(&self) -> QueryBudget {
56        QueryBudget {
57            max_variants: self.max_query_variants,
58        }
59    }
60}
61
62impl Default for KeyBudget {
63    fn default() -> Self {
64        SearchConfig::default().key_budget()
65    }
66}
67
68impl Default for QueryBudget {
69    fn default() -> Self {
70        SearchConfig::default().query_budget()
71    }
72}
73
74/// Matcher implementation selected for fuzzy scoring.
75#[derive(Clone, Copy, Debug, Eq, PartialEq)]
76pub enum MatcherAlgo {
77    /// Yuru's default greedy matcher.
78    Greedy,
79    /// Greedy fzf-style matcher alias.
80    FzfV1,
81    /// Nucleo-backed quality matcher alias.
82    FzfV2,
83    /// Nucleo-backed quality matcher.
84    Nucleo,
85}
86
87/// Secondary sort rule used when scores are equal.
88#[derive(Clone, Copy, Debug, Eq, PartialEq)]
89pub enum Tiebreak {
90    /// Prefer shorter display strings.
91    Length,
92    /// Prefer fewer separated match chunks.
93    Chunk,
94    /// Prefer path-like matches with better pathname position.
95    Pathname,
96    /// Prefer matches closer to the beginning.
97    Begin,
98    /// Prefer matches closer to the end.
99    End,
100    /// Prefer lower original candidate index.
101    Index,
102}
103
104impl Default for SearchConfig {
105    fn default() -> Self {
106        Self {
107            max_query_variants: 8,
108            max_search_keys_per_candidate: 8,
109            max_total_key_bytes_per_candidate: 1024,
110            limit: 10,
111            top_b_for_quality_score: 1000,
112            exact: false,
113            extended: true,
114            case_sensitive: false,
115            disabled: false,
116            no_sort: false,
117            normalize: true,
118            matcher_algo: MatcherAlgo::Greedy,
119            tiebreaks: vec![Tiebreak::Length, Tiebreak::Index],
120        }
121    }
122}