use crate::MapValueExtractor;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum MapValue {
String(String),
I16(i16),
U16(u16),
I32(i32),
U32(u32),
F32(f32),
I64(i64),
U64(u64),
F64(f64),
Bool(bool),
OptionValue(Option<Box<MapValue>>),
}
pub trait HashmapCustom {
fn get_value<T>(&self, key: &str) -> Option<T>
where
T: Copy + 'static,
MapValue: MapValueExtractor<T>;
fn get_value_ref<T>(&self, key: &str) -> Option<&T>
where
MapValue: MapValueExtractor<T>;
fn set_value<T>(&mut self, key: &str, value: T)
where
T: Into<MapValue>;
}
impl HashmapCustom for HashMap<String, MapValue> {
fn get_value<T>(&self, key: &str) -> Option<T>
where
T: Copy + 'static,
MapValue: MapValueExtractor<T>,
{
self.get(key).and_then(MapValue::extract).copied()
}
fn get_value_ref<T>(&self, key: &str) -> Option<&T>
where
MapValue: MapValueExtractor<T>,
{
self.get(key).and_then(MapValue::extract)
}
fn set_value<T>(&mut self, key: &str, value: T)
where
T: Into<MapValue>,
{
self.insert(key.to_string(), value.into());
}
}
#[cfg(test)]
mod tests {
use crate::map_struct::HashmapCustom;
use std::collections::HashMap;
#[test]
fn test_set() {
let mut map = HashMap::new();
map.set_value("&str", "111" as &str);
map.set_value("String", "111".to_string());
map.set_value("i16", 111i16);
map.set_value("u16", 111u16);
map.set_value("i32", 111i32);
map.set_value("u32", 111u32);
map.set_value("f32", 111.11f32);
map.set_value("i64", 111i64);
map.set_value("u64", 111u64);
map.set_value("f64", 111.11f64);
assert_eq!(
Some(&"111".to_string()),
map.get_value_ref::<String>("&str")
);
assert_eq!(None, map.get_value_ref::<String>("&str1"));
assert_eq!(None, map.get_value_ref::<String>("none"));
assert_eq!(Some(111i16), map.get_value::<i16>("i16"));
assert_eq!(Some(111u16), map.get_value::<u16>("u16"));
assert_eq!(Some(111i32), map.get_value::<i32>("i32"));
assert_eq!(Some(111u32), map.get_value::<u32>("u32"));
assert_eq!(Some(111.11f32), map.get_value::<f32>("f32"));
assert_eq!(Some(111i64), map.get_value::<i64>("i64"));
assert_eq!(Some(111u64), map.get_value::<u64>("u64"));
assert_eq!(Some(111.11f64), map.get_value::<f64>("f64"));
}
#[test]
fn test_clone_and_ref() {
let mut map = HashMap::new();
map.set_value("i32", 111);
map.set_value("String", "111".to_string());
let option = map.get_value::<i32>("i32");
assert_eq!(Some(111), option);
let option1 = map.get_value_ref::<String>("String");
assert_eq!(Some(&"111".to_string()), option1);
}
}