trs_dataframe/
candidate.rsuse crate::error::Error;
use crate::Key;
use data_value::DataValue;
pub trait CandidateData:
Default
+ Clone
+ std::fmt::Debug
+ Default
+ IntoIterator<Item = (Key, DataValue)>
+ Send
+ Sync
+ 'static
{
fn get_value(&self, key: &Key) -> Result<DataValue, Error>;
fn get_value_ref(&self, key: &Key) -> Option<&DataValue>;
fn store_value(&mut self, key: &Key, value: DataValue) -> Option<DataValue>;
fn merge(&mut self, other: &Self);
fn keys(&self) -> Vec<Key>;
fn select(&self, keys: &[Key]) -> Vec<DataValue>;
fn remove(&mut self, key: &Key) -> Option<DataValue>;
}
macro_rules! impl_candidate_data_for_hm {
($t: path) => {
impl CandidateData for $t {
fn get_value(&self, key: &Key) -> Result<DataValue, Error> {
Ok(self.get(key).cloned().unwrap_or_else(|| DataValue::Null))
}
fn get_value_ref(&self, key: &Key) -> Option<&DataValue> {
self.get(key)
}
fn store_value(&mut self, key: &Key, value: DataValue) -> Option<DataValue> {
self.insert(key.clone(), value)
}
fn merge(&mut self, other: &Self) {
for (key, value) in other.iter() {
self.store_value(key, value.clone());
}
}
fn keys(&self) -> Vec<Key> {
let mut v = self.keys().cloned().collect::<Vec<_>>();
v.sort();
v
}
fn select(&self, keys: &[Key]) -> Vec<DataValue> {
keys.iter()
.map(|key| self.get_value(key).unwrap_or_default())
.collect()
}
fn remove(&mut self, key: &Key) -> Option<DataValue> {
self.remove(key)
}
}
};
}
impl_candidate_data_for_hm! {::halfbrown::HashMap<Key, DataValue>}
impl_candidate_data_for_hm! {::std::collections::HashMap<Key, DataValue>}
#[cfg(test)]
mod test {
use super::*;
use rstest::*;
#[rstest]
#[case(halfbrown::HashMap::new())]
#[case(std::collections::HashMap::new())]
fn test_candidate_data<T: CandidateData>(#[case] mut candidate: T) {
let key = Key::from("test");
let value = DataValue::from(1);
candidate.store_value(&key, value.clone());
assert_eq!(candidate.get_value(&key).unwrap(), value);
assert_eq!(candidate.get_value_ref(&key).unwrap(), &value);
assert_eq!(candidate.keys(), vec![key.clone()]);
assert_eq!(candidate.select(&[key.clone()]), vec![value.clone()]);
assert_eq!(candidate.remove(&key), Some(value.clone()));
assert_eq!(candidate.remove(&key), None);
}
}