ultra_nlp/_hashmap/
dictionary.rs

1use std::collections::HashMap;
2use crate::{
3    UltraNLPResult,
4    UltraNLPError,
5};
6
7#[derive(Clone)]
8pub struct Dictionary {
9    pub(crate) map: HashMap<String, usize>,
10}
11
12impl Dictionary {
13    pub fn new<T: AsRef<str>, I: IntoIterator<Item = T>>(
14        patterns: I
15    ) -> UltraNLPResult<Self> {
16        let patterns_with_values = prepare_patterns_for_dictionary(patterns)?;
17        if patterns_with_values.len() == 0 {
18            return Err(UltraNLPError::new("The patterns cannot be empty"));
19        }
20
21        let mut map: HashMap<String, usize> = HashMap::new();
22        patterns_with_values
23            .into_iter()
24            .try_for_each(|(pattern, value)| {
25                let result = map.insert(pattern, value);
26
27                if let Some(_) = result {
28                    Err(UltraNLPError::new("The patterns are not unique"))
29                } else {
30                    Ok(())
31                }
32            })?;
33
34        Ok(Self { map })
35    }
36}
37
38fn prepare_patterns_for_dictionary<
39    T: AsRef<str>,
40    I: IntoIterator<Item = T>
41>(
42    patterns: I,
43) -> UltraNLPResult<Vec<(String, usize)>> {
44    let patterns_with_values = patterns
45        .into_iter()
46        .enumerate()
47        .map(|(index, pattern)| -> Result<(String, usize), _>{
48            let pattern = pattern
49                .as_ref()
50                .to_lowercase();
51
52            let value = usize::try_from(index)
53                .map_err(|err| UltraNLPError::new(err.to_string()))?;
54
55            Ok((pattern, value))
56        })
57        .collect::<Result<Vec<_>, _>>()?;
58
59    Ok(patterns_with_values)
60}
61
62#[cfg(test)]
63mod tests {
64    use crate::hashmap::Dictionary;
65
66    #[test]
67    fn test_empty_patterns() {
68        let patterns: Vec<&str> = vec![];
69
70        assert!(Dictionary::new(patterns).is_err());
71    }
72
73    #[test]
74    fn test_patterns() {
75        let patterns: Vec<&str> = vec!["foo", "bar"];
76
77        Dictionary::new(patterns)
78            .unwrap();
79    }
80
81    #[test]
82    fn test_same_patterns() {
83        let patterns: Vec<&str> = vec!["foo", "FOO"];
84
85        assert!(Dictionary::new(patterns).is_err());
86    }
87}