fuzzy_regex/types.rs
1//! Core types for fuzzy matching limits and penalties.
2pub type NumEdits = u8;
3pub type Distance = u16;
4
5/// Limits on the number of edit operations allowed during fuzzy matching.
6///
7/// Edit operations include:
8/// - **Insertions**: Extra characters in the text that aren't in the pattern
9/// - **Deletions**: Characters in the pattern that are missing from the text
10/// - **Substitutions**: Characters that differ between pattern and text
11/// - **Swaps**: Adjacent character transpositions
12///
13/// You can set a total edit limit with `edits()`, or individual limits for each
14/// operation type. When individual limits are set without a total, the total is
15/// computed as the sum of individual limits.
16#[derive(Debug, Default, Clone, PartialEq)]
17pub struct FuzzyLimits {
18 insertions: Option<NumEdits>,
19 deletions: Option<NumEdits>,
20 substitutions: Option<NumEdits>,
21 swaps: Option<NumEdits>,
22 edits: Option<NumEdits>,
23}
24
25impl FuzzyLimits {
26 /// Create new empty fuzzy limits (exact match only).
27 #[must_use]
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 /// Set the maximum number of insertions allowed.
33 #[must_use]
34 pub fn insertions(mut self, num: NumEdits) -> Self {
35 self.insertions = Some(num);
36 self
37 }
38
39 /// Set the maximum number of deletions allowed.
40 #[must_use]
41 pub fn deletions(mut self, num: NumEdits) -> Self {
42 self.deletions = Some(num);
43 self
44 }
45
46 /// Set the maximum number of substitutions allowed.
47 #[must_use]
48 pub fn substitutions(mut self, num: NumEdits) -> Self {
49 self.substitutions = Some(num);
50 self
51 }
52
53 /// Set the maximum number of swaps (transpositions) allowed.
54 #[must_use]
55 pub fn swaps(mut self, num: NumEdits) -> Self {
56 self.swaps = Some(num);
57 self
58 }
59
60 /// Set the maximum total number of edits allowed.
61 #[must_use]
62 pub fn edits(mut self, num: NumEdits) -> Self {
63 self.edits = Some(num);
64 self
65 }
66
67 /// Get the maximum total edits allowed.
68 #[must_use]
69 pub fn get_edits(&self) -> Option<NumEdits> {
70 self.edits
71 }
72
73 /// Get the maximum insertions allowed.
74 #[must_use]
75 pub fn get_insertions(&self) -> Option<NumEdits> {
76 self.insertions
77 }
78
79 /// Get the maximum deletions allowed.
80 #[must_use]
81 pub fn get_deletions(&self) -> Option<NumEdits> {
82 self.deletions
83 }
84
85 /// Get the maximum substitutions allowed.
86 #[must_use]
87 pub fn get_substitutions(&self) -> Option<NumEdits> {
88 self.substitutions
89 }
90
91 /// Get the maximum swaps allowed.
92 #[must_use]
93 pub fn get_swaps(&self) -> Option<NumEdits> {
94 self.swaps
95 }
96}
97
98/// Penalty weights for different edit operations.
99///
100/// These weights are used to calculate a weighted edit distance where different
101/// operations can have different costs. Lower penalties mean the operation is
102/// considered "cheaper" during matching.
103#[derive(Debug, Clone)]
104pub struct FuzzyPenalties {
105 /// Penalty for inserting a character (extra char in text).
106 pub insertion: f32,
107 /// Penalty for deleting a character (missing char from pattern).
108 pub deletion: f32,
109 /// Penalty for substituting a character.
110 pub substitution: f32,
111 /// Penalty for swapping adjacent characters.
112 pub swap: f32,
113}
114
115impl Default for FuzzyPenalties {
116 fn default() -> Self {
117 let m = 1.3;
118 Self {
119 substitution: 1.1 * m,
120 insertion: 0.4 * m,
121 deletion: 0.7 * m,
122 swap: 0.4 * m,
123 }
124 }
125}
126
127impl FuzzyPenalties {
128 /// Set the insertion penalty.
129 #[must_use]
130 pub fn insertion(mut self, penalty: f32) -> Self {
131 self.insertion = penalty;
132 self
133 }
134
135 /// Set the deletion penalty.
136 #[must_use]
137 pub fn deletion(mut self, penalty: f32) -> Self {
138 self.deletion = penalty;
139 self
140 }
141
142 /// Set the substitution penalty.
143 #[must_use]
144 pub fn substitution(mut self, penalty: f32) -> Self {
145 self.substitution = penalty;
146 self
147 }
148
149 /// Set the swap penalty.
150 #[must_use]
151 pub fn swap(mut self, penalty: f32) -> Self {
152 self.swap = penalty;
153 self
154 }
155}