elasticsearch_dsl/search/queries/params/fuzziness.rs
1use serde::{Serialize, Serializer};
2use std::ops::Range;
3
4/// Some queries and APIs support parameters to allow inexact _fuzzy_ matching,
5/// using the `fuzziness` parameter.
6///
7/// When querying `text` or `keyword` fields, `fuzziness` is interpreted as a
8/// [Levenshtein Edit Distance](https://en.wikipedia.org/wiki/Levenshtein_distance)
9/// — the number of one character changes that need to be made to one string to make it the same as another string.
10///
11/// <https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness>
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum Fuzziness {
14 /// Generates an edit distance based on the length of the term.
15 ///
16 /// `AUTO` should generally be the preferred value for `fuzziness`.
17 Auto,
18
19 /// Low and high distance arguments may be optionally provided
20 /// `AUTO:[low],[high]`. If not specified, the default values are 3 and 6,
21 /// equivalent to `AUTO:3,6` that make for lengths:
22 ///
23 /// **`0..2`**
24 ///
25 /// Must match exactly
26 ///
27 /// **`3..5`**
28 ///
29 /// One edit allowed
30 ///
31 /// **`>5`**
32 ///
33 /// Two edits allowed
34 Range(u8, u8),
35
36 /// The maximum allowed Levenshtein Edit Distance (or number of edits)
37 Distance(u8),
38}
39
40impl Serialize for Fuzziness {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where
43 S: Serializer,
44 {
45 match self {
46 Self::Auto => "AUTO".serialize(serializer),
47 Self::Range(start, end) => format!("AUTO:{start},{end}").serialize(serializer),
48 Self::Distance(d) => d.serialize(serializer),
49 }
50 }
51}
52
53impl From<Range<u8>> for Fuzziness {
54 fn from(v: Range<u8>) -> Self {
55 Self::Range(v.start, v.end)
56 }
57}
58
59impl From<[u8; 2]> for Fuzziness {
60 fn from(v: [u8; 2]) -> Self {
61 Self::Range(v[0], v[1])
62 }
63}
64
65impl From<u8> for Fuzziness {
66 fn from(v: u8) -> Self {
67 Self::Distance(v)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::util::assert_serialize;
75
76 #[test]
77 fn implements_from_u8() {
78 let result = Fuzziness::from(8);
79
80 let expectation = Fuzziness::Distance(8);
81
82 assert_eq!(result, expectation);
83 }
84
85 #[test]
86 fn implements_from_range_u8() {
87 let result = Fuzziness::from(0..2);
88
89 let expectation = Fuzziness::Range(0, 2);
90
91 assert_eq!(result, expectation);
92 }
93
94 #[test]
95 fn serializes() {
96 assert_serialize(
97 [
98 Fuzziness::Auto,
99 Fuzziness::Range(0, 2),
100 Fuzziness::Distance(5),
101 ],
102 json!(["AUTO", "AUTO:0,2", 5,]),
103 )
104 }
105}