use cdumay_core::ErrorConverter;
use serde::Deserialize;
use serde::Serialize;
use std::collections::BTreeMap;
pub trait ContextDump {
fn dump(&self) -> std::collections::BTreeMap<String, serde_value::Value>;
}
pub trait Contextualize: Sized + Serialize {
fn new() -> Self;
fn insert(&mut self, k: String, v: serde_value::Value);
fn get(&self, k: &str) -> Option<&serde_value::Value>;
fn extend(&mut self, data: BTreeMap<String, serde_value::Value>);
fn inner(&self) -> BTreeMap<String, serde_value::Value>;
#[cfg(feature = "json")]
fn from_json(json: &str) -> cdumay_core::Result<Self> {
Ok({
let mut ctx = Self::new();
let details = serde_json::from_str::<BTreeMap<String, serde_json::Value>>(json)
.map_err(|err| cdumay_json::JsonErrorConverter::convert_error(&err, Some("Failed to load context".to_string()), ctx.inner()))?
.into_iter()
.map(|(key, value)| (key, serde_value::Value::deserialize(value).unwrap()))
.collect();
ctx.extend(details);
ctx
})
}
#[cfg(feature = "json")]
fn to_json(&self, pretty: bool) -> cdumay_core::Result<String> {
match pretty {
true => Ok(serde_json::to_string_pretty(&self.inner())
.map_err(|err| cdumay_json::JsonErrorConverter::convert_error(&err, Some("Failed to dump context".to_string()), self.inner()))?),
false => Ok(serde_json::to_string(&self.inner())
.map_err(|err| cdumay_json::JsonErrorConverter::convert_error(&err, Some("Failed to dump context".to_string()), self.inner()))?),
}
}
#[cfg(feature = "toml")]
fn from_toml(toml: &str) -> cdumay_core::Result<Self> {
Ok({
let mut ctx = Self::new();
ctx.extend({
toml::from_str::<BTreeMap<String, serde_value::Value>>(toml)
.map_err(|err| {
cdumay_toml::TomlDeserializeErrorConverter::convert_error(&err, Some("Failed to load context".to_string()), ctx.inner())
})?
.into_iter()
.map(|(key, value)| (key, serde_value::Value::deserialize(value).unwrap()))
.collect()
});
ctx
})
}
#[cfg(feature = "toml")]
fn to_toml(&self, pretty: bool) -> cdumay_core::Result<String> {
match pretty {
true => Ok(toml::to_string_pretty(&self.inner()).map_err(|err| {
cdumay_toml::TomlSerializeErrorConverter::convert_error(&err, Some("Failed to dump context".to_string()), self.inner())
})?),
false => Ok(toml::to_string(&self.inner()).map_err(|err| {
cdumay_toml::TomlSerializeErrorConverter::convert_error(&err, Some("Failed to dump context".to_string()), self.inner())
})?),
}
}
#[cfg(feature = "yaml")]
fn from_yaml(yaml: &str) -> cdumay_core::Result<Self> {
Ok({
let mut ctx = Self::new();
ctx.extend({
serde_yaml::from_str::<BTreeMap<String, serde_json::Value>>(yaml)
.map_err(|err| cdumay_yaml::YamlErrorConverter::convert_error(&err, Some("Failed to load context".to_string()), ctx.inner()))?
.into_iter()
.map(|(key, value)| (key, serde_value::Value::deserialize(value).unwrap()))
.collect()
});
ctx
})
}
#[cfg(feature = "yaml")]
fn to_yaml(&self) -> cdumay_core::Result<String> {
Ok(serde_yaml::to_string(&self.inner())
.map_err(|err| cdumay_yaml::YamlErrorConverter::convert_error(&err, Some("Failed to dump context".to_string()), self.inner()))?)
}
}
#[derive(Default, Serialize, Deserialize, Debug)]
pub struct Context {
data: BTreeMap<String, serde_value::Value>,
}
impl Contextualize for Context {
fn new() -> Self {
Self::default()
}
fn insert(&mut self, k: String, v: serde_value::Value) {
self.data.insert(k, v);
}
fn get(&self, k: &str) -> Option<&serde_value::Value> {
self.data.get(k)
}
fn extend(&mut self, data: BTreeMap<String, serde_value::Value>) {
self.data.extend(data);
}
fn inner(&self) -> BTreeMap<String, serde_value::Value> {
self.data.clone()
}
}
impl ContextDump for Context {
fn dump(&self) -> BTreeMap<String, serde_value::Value> {
self.data.clone()
}
}