trs_dataframe/
candidate.rs

1use crate::error::Error;
2use crate::Key;
3use data_value::DataValue;
4/// Basic trait for the work with the candidate data
5/// This trait is used to store and retrive the data for the candidates
6pub trait CandidateData:
7    Default
8    + Clone
9    + std::fmt::Debug
10    + Default
11    + IntoIterator<Item = (Key, DataValue)>
12    + Send
13    + Sync
14    + 'static
15{
16    /// Get the value for the key [`Key`]
17    fn get_value(&self, key: &Key) -> Result<DataValue, Error>;
18    fn get_value_ref(&self, key: &Key) -> Option<&DataValue>;
19    /// Store the value [`DataValue`] for the key [`Key`] and return the old value if any
20    fn store_value(&mut self, key: &Key, value: DataValue) -> Option<DataValue>;
21    /// Merge the data from the other candidate
22    fn merge(&mut self, other: &Self);
23    /// Get the keys for the candidate
24    fn keys(&self) -> Vec<Key>;
25    /// Select the values for the keys
26    fn select(&self, keys: &[Key]) -> Vec<DataValue>;
27    /// Remove data from the candidate
28    fn remove(&mut self, key: &Key) -> Option<DataValue>;
29}
30macro_rules! impl_candidate_data_for_hm {
31    ($t: path) => {
32        impl CandidateData for $t {
33            fn get_value(&self, key: &Key) -> Result<DataValue, Error> {
34                Ok(self.get(key).cloned().unwrap_or_else(|| DataValue::Null))
35            }
36            fn get_value_ref(&self, key: &Key) -> Option<&DataValue> {
37                self.get(key)
38            }
39            fn store_value(&mut self, key: &Key, value: DataValue) -> Option<DataValue> {
40                self.insert(key.clone(), value)
41            }
42            fn merge(&mut self, other: &Self) {
43                for (key, value) in other.iter() {
44                    self.store_value(key, value.clone());
45                }
46            }
47            fn keys(&self) -> Vec<Key> {
48                let mut v = self.keys().cloned().collect::<Vec<_>>();
49                v.sort();
50                v
51            }
52            fn select(&self, keys: &[Key]) -> Vec<DataValue> {
53                keys.iter()
54                    .map(|key| self.get_value(key).unwrap_or_default())
55                    .collect()
56            }
57
58            fn remove(&mut self, key: &Key) -> Option<DataValue> {
59                self.remove(key)
60            }
61        }
62    };
63}
64
65impl_candidate_data_for_hm! {::halfbrown::HashMap<Key, DataValue>}
66impl_candidate_data_for_hm! {::std::collections::HashMap<Key, DataValue>}
67
68#[cfg(test)]
69mod test {
70    use super::*;
71    use rstest::*;
72
73    #[rstest]
74    #[case(halfbrown::HashMap::new())]
75    #[case(std::collections::HashMap::new())]
76    fn test_candidate_data<T: CandidateData>(#[case] mut candidate: T) {
77        let key = Key::from("test");
78        let value = DataValue::from(1);
79        candidate.store_value(&key, value.clone());
80        assert_eq!(candidate.get_value(&key).unwrap(), value);
81        assert_eq!(candidate.get_value_ref(&key).unwrap(), &value);
82        assert_eq!(candidate.keys(), vec![key.clone()]);
83        assert_eq!(candidate.select(&[key.clone()]), vec![value.clone()]);
84        assert_eq!(candidate.remove(&key), Some(value.clone()));
85        assert_eq!(candidate.remove(&key), None);
86    }
87}