1pub trait Module: Send + Sync + 'static {
11 fn name(&self) -> &'static str;
13}
14
15#[derive(Default)]
17pub struct ModuleRegistry {
18 modules: Vec<Box<dyn Module>>,
19}
20
21impl ModuleRegistry {
22 pub fn new() -> Self {
23 Self::default()
24 }
25
26 pub fn register(&mut self, module: impl Module) -> &mut Self {
29 self.modules.push(Box::new(module));
30 self
31 }
32
33 pub fn iter(&self) -> impl Iterator<Item = &dyn Module> + '_ {
34 self.modules.iter().map(|m| m.as_ref())
35 }
36
37 pub fn len(&self) -> usize {
38 self.modules.len()
39 }
40
41 pub fn is_empty(&self) -> bool {
42 self.modules.is_empty()
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 struct A;
51 struct B;
52
53 impl Module for A {
54 fn name(&self) -> &'static str {
55 "a"
56 }
57 }
58
59 impl Module for B {
60 fn name(&self) -> &'static str {
61 "b"
62 }
63 }
64
65 #[test]
66 fn preserves_registration_order() {
67 let mut registry = ModuleRegistry::new();
68 registry.register(A).register(B);
69 let names: Vec<_> = registry.iter().map(|m| m.name()).collect();
70 assert_eq!(names, ["a", "b"]);
71 }
72}