use serde_json::Value;
pub type Metadata = Value;
pub trait MetadataExt {
fn get_str(&self, key: &str) -> Option<&str>;
fn get_i64(&self, key: &str) -> Option<i64>;
fn get_f64(&self, key: &str) -> Option<f64>;
fn get_bool(&self, key: &str) -> Option<bool>;
fn has_key(&self, key: &str) -> bool;
}
impl MetadataExt for Metadata {
fn get_str(&self, key: &str) -> Option<&str> {
self.get(key)?.as_str()
}
fn get_i64(&self, key: &str) -> Option<i64> {
self.get(key)?.as_i64()
}
fn get_f64(&self, key: &str) -> Option<f64> {
self.get(key)?.as_f64()
}
fn get_bool(&self, key: &str) -> Option<bool> {
self.get(key)?.as_bool()
}
fn has_key(&self, key: &str) -> bool {
self.get(key).is_some()
}
}
pub fn metadata_from_kv(key: &str, value: &str) -> Metadata {
serde_json::json!({ key: value })
}
pub fn metadata_from_hashmap(map: std::collections::HashMap<String, String>) -> Metadata {
serde_json::to_value(map).unwrap_or(Value::Null)
}
pub fn metadata_from_map(map: serde_json::Map<String, Value>) -> Metadata {
Value::Object(map)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metadata_ext() {
let meta: Metadata = serde_json::json!({
"name": "test",
"count": 42,
"score": 3.14,
"active": true
});
assert_eq!(meta.get_str("name"), Some("test"));
assert_eq!(meta.get_i64("count"), Some(42));
assert!((meta.get_f64("score").unwrap() - 3.14).abs() < 1e-6);
assert_eq!(meta.get_bool("active"), Some(true));
assert!(meta.has_key("name"));
assert!(!meta.has_key("missing"));
}
}