use std::fmt;
use std::collections::{hash_map, HashMap};
#[macro_export]
macro_rules! context {
($($key:ty: $value:expr),*) => ({
use $crate::Context;
let mut context = Context::new();
$(
context.set(stringify!($key), $value);
)*
context
})
}
#[derive(Debug, Clone)]
pub struct Context(HashMap<String, String>);
impl Context {
pub fn new() -> Self {
Self { 0: HashMap::new() }
}
pub fn set<S>(&mut self, key: S, value: S)
where
S: Into<String>,
{
let key = key.into();
let value = value.into();
if value == "" {
self.0.remove(&key);
} else {
self.0.insert(key, value);
}
}
pub fn get(&self, key: &str) -> Option<&String> {
self.0.get(key)
}
pub fn merge(&self, context: Self) -> Self {
let mut merged_context = Self { 0: self.0.clone() };
for (key, val) in context.0.into_iter() {
merged_context.set(key, val);
}
merged_context
}
pub fn iter(&self) -> hash_map::Iter<String, String> {
self.0.iter()
}
pub fn into_iter(self) -> hash_map::IntoIter<String, String> {
self.0.into_iter()
}
}
impl fmt::Display for Context {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let messages: Vec<_> = self
.0
.iter()
.map(|(key, val)| format!("{}: \"{}\"", key, val))
.collect();
write!(f, "{{ {} }}", messages.join(", "))
}
}