use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::HashMap;
use std::fmt;
#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq, Eq)]
pub struct Context {
#[serde(flatten)] data: HashMap<String, Value>,
}
impl Context {
pub fn new() -> Self {
Self {
data: HashMap::new(),
}
}
pub fn from_value(value: Value) -> Self {
match value {
Value::Object(map) => Self {
data: map.into_iter().collect(),
},
_ => {
eprintln!("Warning: Context::from_value expected a JSON object, received {:?}. Returning empty context.", value);
Self::new() }
}
}
pub fn set<T: Serialize>(&mut self, key: &str, value: T) -> Result<(), serde_json::Error> {
let json_value = serde_json::to_value(value)?;
self.data.insert(key.to_string(), json_value);
Ok(())
}
pub fn get<T: DeserializeOwned>(&self, key: &str) -> Option<Result<T, serde_json::Error>> {
self.data
.get(key)
.map(|value| serde_json::from_value(value.clone())) }
pub fn get_value(&self, key: &str) -> Option<&Value> {
self.data.get(key)
}
pub fn has(&self, key: &str) -> bool {
self.data.contains_key(key)
}
pub fn remove(&mut self, key: &str) -> Option<Value> {
self.data.remove(key)
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
}
impl fmt::Display for Context {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match serde_json::to_string_pretty(&self.data) {
Ok(pretty_json) => write!(f, "{}", pretty_json),
Err(_) => {
write!(f, "{:?}", self.data)
}
}
}
}