threshold_dict/
lib.rs

1#![allow(clippy::type_complexity)]
2
3use std::collections::BTreeMap;
4use std::fmt::Debug;
5use std::ops::Bound::{Included, Unbounded};
6
7pub struct ThresholdDict<K, V> {
8    tree: BTreeMap<K, V>,
9}
10
11impl<K: Ord, V> From<Vec<(K, V)>> for ThresholdDict<K, V> {
12    fn from(kv: Vec<(K, V)>) -> Self {
13        let tree = BTreeMap::from_iter(kv);
14        Self::new(tree)
15    }
16}
17
18impl<K: Ord, V> ThresholdDict<K, V> {
19    /// default constructor
20    pub fn new(tree: BTreeMap<K, V>) -> Self {
21        Self { tree }
22    }
23
24    /// The query method.
25    /// A value corresponding the smallest key which is
26    /// greater than or equal to the query key is returned.
27    pub fn query(&self, key: &K) -> Option<&V> {
28        let query = (Included(key), Unbounded);
29        let result = self.tree.range(query).next();
30        result.map(|(_, v)| v)
31    }
32}
33
34impl<K: Ord + Clone, V: Clone> Clone for ThresholdDict<K, V> {
35    fn clone(&self) -> Self {
36        Self {
37            tree: self.tree.clone(),
38        }
39    }
40}
41
42impl<K: Ord + Debug, V: Debug> Debug for ThresholdDict<K, V> {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        f.debug_struct("ThresholdDict")
45            .field("tree", &self.tree)
46            .finish()
47    }
48}
49
50#[cfg(test)]
51mod test {
52    use std::collections::BTreeMap;
53
54    use super::ThresholdDict;
55
56    #[test]
57    fn test_from_btree_map() {
58        let map = BTreeMap::from([(10, 100), (20, 150), (50, 300)]);
59        let dict = ThresholdDict::new(map);
60        let correct_dict = ThresholdDict::from(vec![(10, 100), (20, 150), (50, 300)]);
61        assert_eq!(dict.tree, correct_dict.tree);
62    }
63
64    #[test]
65    fn test_clone() {
66        let dict = ThresholdDict::from(vec![(10, 100), (20, 150), (50, 300)]);
67        let dict2 = dict.clone();
68        assert_eq!(dict.tree, dict2.tree);
69    }
70
71    #[test]
72    fn test_query() {
73        let dict = ThresholdDict::from(vec![(10, 100), (20, 150), (50, 300)]);
74        assert_eq!(dict.query(&0), Some(&100));
75        assert_eq!(dict.query(&10), Some(&100));
76        assert_eq!(dict.query(&15), Some(&150));
77        assert_eq!(dict.query(&40), Some(&300));
78        assert_eq!(dict.query(&50), Some(&300));
79        assert_eq!(dict.query(&60), None);
80    }
81}