use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)]
#[serde(transparent)]
pub struct Metadata(HashMap<String, String>);
impl Metadata {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn get(&self, key: &str) -> Option<&str> {
self.0.get(key).map(|v| v.as_str())
}
pub fn insert(&mut self, key: &str, value: &str) -> Option<String> {
self.0.insert(key.to_owned(), value.to_owned())
}
pub fn iter(&self) -> impl Iterator<Item = (&str, &str)> {
self.0.iter().map(|(k, v)| (k.as_str(), v.as_str()))
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn len(&self) -> usize {
self.0.len()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_is_empty() {
let meta = Metadata::new();
assert!(meta.is_empty());
assert_eq!(meta.len(), 0);
}
#[test]
fn test_insert_and_get() {
let mut meta = Metadata::new();
meta.insert("team", "platform");
assert_eq!(meta.get("team"), Some("platform"));
assert_eq!(meta.get("missing"), None);
assert!(!meta.is_empty());
assert_eq!(meta.len(), 1);
}
#[test]
fn test_serde_round_trip() {
let mut meta = Metadata::new();
meta.insert("owner", "alice");
meta.insert("cost-center", "eng");
let json = serde_json::to_string(&meta).unwrap();
let deserialized: Metadata = serde_json::from_str(&json).unwrap();
assert_eq!(meta, deserialized);
}
#[test]
fn test_iter() {
let mut meta = Metadata::new();
meta.insert("a", "1");
meta.insert("b", "2");
let pairs: Vec<_> = meta.iter().collect();
assert_eq!(pairs.len(), 2);
}
#[test]
fn test_insert_returns_previous() {
let mut meta = Metadata::new();
let prev = meta.insert("key", "value1");
assert!(prev.is_none());
let prev = meta.insert("key", "value2");
assert_eq!(prev, Some("value1".to_owned()));
assert_eq!(meta.get("key"), Some("value2"));
}
#[test]
fn test_default() {
let meta = Metadata::default();
assert!(meta.is_empty());
assert_eq!(meta.len(), 0);
}
#[test]
fn test_debug() {
let mut meta = Metadata::new();
meta.insert("k", "v");
let debug = format!("{meta:?}");
assert!(debug.contains("Metadata"));
}
#[test]
fn test_clone_eq() {
let mut meta = Metadata::new();
meta.insert("x", "y");
let cloned = meta.clone();
assert_eq!(meta, cloned);
}
}