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    /// &nbsp;&nbsp;&nbsp;&nbsp;Must match exactly
26    ///
27    /// **`3..5`**
28    ///
29    /// &nbsp;&nbsp;&nbsp;&nbsp;One edit allowed
30    ///
31    /// **`>5`**
32    ///
33    /// &nbsp;&nbsp;&nbsp;&nbsp;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}