1use std::collections::HashMap;
2
3use bytes::Bytes;
4
5pub struct ServiceEntry {
7 pub capabilities: Bytes,
9}
10
11pub struct ServiceRegistry {
20 services: HashMap<String, ServiceEntry>,
21}
22
23impl ServiceRegistry {
24 pub fn new() -> Self {
25 Self {
26 services: HashMap::new(),
27 }
28 }
29
30 pub fn register(&mut self, name: impl Into<String>, capabilities: Bytes) {
32 self.services
33 .insert(name.into(), ServiceEntry { capabilities });
34 }
35
36 pub fn lookup(&self, name: &str) -> Option<&ServiceEntry> {
38 self.services.get(name)
39 }
40
41 pub fn unregister(&mut self, name: &str) -> bool {
43 self.services.remove(name).is_some()
44 }
45
46 pub fn service_count(&self) -> usize {
47 self.services.len()
48 }
49}
50
51impl Default for ServiceRegistry {
52 fn default() -> Self {
53 Self::new()
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn register_and_lookup() {
63 let mut reg = ServiceRegistry::new();
64 reg.register("foo", Bytes::from_static(b"caps"));
65 let entry = reg.lookup("foo").unwrap();
66 assert_eq!(entry.capabilities, Bytes::from_static(b"caps"));
67 }
68
69 #[test]
70 fn lookup_missing_returns_none() {
71 let reg = ServiceRegistry::new();
72 assert!(reg.lookup("missing").is_none());
73 }
74
75 #[test]
76 fn unregister_removes_entry() {
77 let mut reg = ServiceRegistry::new();
78 reg.register("bar", Bytes::new());
79 assert!(reg.unregister("bar"));
80 assert!(reg.lookup("bar").is_none());
81 }
82
83 #[test]
84 fn unregister_nonexistent_returns_false() {
85 let mut reg = ServiceRegistry::new();
86 assert!(!reg.unregister("nope"));
87 }
88
89 #[test]
90 fn service_count() {
91 let mut reg = ServiceRegistry::new();
92 assert_eq!(reg.service_count(), 0);
93 reg.register("a", Bytes::new());
94 reg.register("b", Bytes::new());
95 assert_eq!(reg.service_count(), 2);
96 reg.unregister("a");
97 assert_eq!(reg.service_count(), 1);
98 }
99}