this/server/
entity_registry.rs1use axum::Router;
4use std::collections::HashMap;
5
6pub trait EntityDescriptor: Send + Sync {
11 fn entity_type(&self) -> &str;
13
14 fn plural(&self) -> &str;
16
17 fn build_routes(&self) -> Router;
24}
25
26#[derive(Default)]
31pub struct EntityRegistry {
32 descriptors: HashMap<String, Box<dyn EntityDescriptor>>,
33}
34
35impl EntityRegistry {
36 pub fn new() -> Self {
38 Self {
39 descriptors: HashMap::new(),
40 }
41 }
42
43 pub fn register(&mut self, descriptor: Box<dyn EntityDescriptor>) {
47 let entity_type = descriptor.entity_type().to_string();
48 self.descriptors.insert(entity_type, descriptor);
49 }
50
51 pub fn build_routes(&self) -> Router {
55 let mut router = Router::new();
56
57 for descriptor in self.descriptors.values() {
58 router = router.merge(descriptor.build_routes());
59 }
60
61 router
62 }
63
64 pub fn entity_types(&self) -> Vec<&str> {
66 self.descriptors.keys().map(|s| s.as_str()).collect()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 struct MockDescriptor {
76 entity_type: String,
77 plural: String,
78 }
79
80 impl MockDescriptor {
81 fn new(entity_type: &str, plural: &str) -> Self {
82 Self {
83 entity_type: entity_type.to_string(),
84 plural: plural.to_string(),
85 }
86 }
87 }
88
89 impl EntityDescriptor for MockDescriptor {
90 fn entity_type(&self) -> &str {
91 &self.entity_type
92 }
93
94 fn plural(&self) -> &str {
95 &self.plural
96 }
97
98 fn build_routes(&self) -> Router {
99 Router::new()
100 }
101 }
102
103 #[test]
104 fn test_new_registry_is_empty() {
105 let registry = EntityRegistry::new();
106 assert!(registry.entity_types().is_empty());
107 }
108
109 #[test]
110 fn test_default_registry_is_empty() {
111 let registry = EntityRegistry::default();
112 assert!(registry.entity_types().is_empty());
113 }
114
115 #[test]
116 fn test_register_single_entity() {
117 let mut registry = EntityRegistry::new();
118 registry.register(Box::new(MockDescriptor::new("order", "orders")));
119 let types = registry.entity_types();
120 assert_eq!(types.len(), 1);
121 assert!(types.contains(&"order"));
122 }
123
124 #[test]
125 fn test_register_multiple_entities() {
126 let mut registry = EntityRegistry::new();
127 registry.register(Box::new(MockDescriptor::new("order", "orders")));
128 registry.register(Box::new(MockDescriptor::new("invoice", "invoices")));
129 registry.register(Box::new(MockDescriptor::new("user", "users")));
130 assert_eq!(registry.entity_types().len(), 3);
131 }
132
133 #[test]
134 fn test_register_duplicate_replaces() {
135 let mut registry = EntityRegistry::new();
136 registry.register(Box::new(MockDescriptor::new("order", "orders")));
137 registry.register(Box::new(MockDescriptor::new("order", "commandes")));
138 assert_eq!(registry.entity_types().len(), 1);
140 }
141
142 #[test]
143 fn test_build_routes_empty_registry() {
144 let registry = EntityRegistry::new();
145 let _router = registry.build_routes(); }
147
148 #[test]
149 fn test_build_routes_with_entities() {
150 let mut registry = EntityRegistry::new();
151 registry.register(Box::new(MockDescriptor::new("order", "orders")));
152 registry.register(Box::new(MockDescriptor::new("invoice", "invoices")));
153 let _router = registry.build_routes(); }
155}