pub trait Registry {
type Value;
fn get(&self, key: &str) -> Option<Self::Value>;
fn list_keys(&self) -> Vec<String>;
fn contains(&self, key: &str) -> bool {
self.get(key).is_some()
}
fn count(&self) -> usize {
self.list_keys().len()
}
fn is_empty(&self) -> bool {
self.count() == 0
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::BTreeMap;
struct SimpleRegistry {
map: BTreeMap<String, String>,
}
impl Registry for SimpleRegistry {
type Value = String;
fn get(&self, key: &str) -> Option<String> {
self.map.get(key).cloned()
}
fn list_keys(&self) -> Vec<String> {
self.map.keys().cloned().collect()
}
fn count(&self) -> usize {
self.map.len()
}
}
#[test]
fn empty_registry() {
let reg = SimpleRegistry {
map: BTreeMap::new(),
};
assert!(reg.is_empty());
assert_eq!(reg.count(), 0);
assert!(reg.list_keys().is_empty());
assert!(!reg.contains("anything"));
assert!(reg.get("anything").is_none());
}
#[test]
fn basic_operations() {
let mut map = BTreeMap::new();
map.insert("alpha".into(), "one".into());
map.insert("beta".into(), "two".into());
let reg = SimpleRegistry { map };
assert!(!reg.is_empty());
assert_eq!(reg.count(), 2);
assert!(reg.contains("alpha"));
assert!(!reg.contains("gamma"));
assert_eq!(reg.get("beta"), Some("two".into()));
assert_eq!(reg.list_keys(), vec!["alpha", "beta"]);
}
#[test]
fn trait_object_works() {
let mut map = BTreeMap::new();
map.insert("key".into(), "val".into());
let reg = SimpleRegistry { map };
let dyn_reg: &dyn Registry<Value = String> = ®
assert_eq!(dyn_reg.count(), 1);
assert_eq!(dyn_reg.get("key"), Some("val".into()));
}
}