use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub type PropertyBag = HashMap<String, serde_json::Value>;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Extension {
pub name: String,
pub version: Option<String>,
#[serde(flatten)]
pub properties: Option<PropertyBag>,
}
impl Extension {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
version: None,
properties: None,
}
}
pub fn with_version(mut self, version: impl Into<String>) -> Self {
self.version = Some(version.into());
self
}
pub fn add_property(mut self, key: impl Into<String>, value: serde_json::Value) -> Self {
self.properties
.get_or_insert_with(HashMap::new)
.insert(key.into(), value);
self
}
}
pub trait WithProperties {
fn add_property(&mut self, key: String, value: serde_json::Value);
fn get_property(&self, key: &str) -> Option<&serde_json::Value>;
}
pub mod property_utils {
use super::*;
pub fn single_property(key: impl Into<String>, value: serde_json::Value) -> PropertyBag {
let mut bag = HashMap::new();
bag.insert(key.into(), value);
bag
}
pub fn merge_properties(mut base: PropertyBag, additional: PropertyBag) -> PropertyBag {
base.extend(additional);
base
}
pub fn string_value(value: impl Into<String>) -> serde_json::Value {
serde_json::Value::String(value.into())
}
pub fn number_value(value: impl Into<serde_json::Number>) -> serde_json::Value {
serde_json::Value::Number(value.into())
}
pub fn bool_value(value: bool) -> serde_json::Value {
serde_json::Value::Bool(value)
}
pub fn array_value(values: Vec<serde_json::Value>) -> serde_json::Value {
serde_json::Value::Array(values)
}
pub fn object_value(properties: PropertyBag) -> serde_json::Value {
serde_json::Value::Object(properties.into_iter().collect())
}
}