rabbit_digger/
registry.rs

1//! A registry with plugin name
2
3use anyhow::{anyhow, Result};
4use rd_interface::{registry::FromConfig, Net, Server, Value};
5use std::{collections::HashMap, fmt};
6
7pub struct NetItem {
8    pub plugin_name: String,
9    pub factory: FromConfig<Net>,
10}
11
12pub struct ServerItem {
13    pub plugin_name: String,
14    pub factory: FromConfig<Server>,
15}
16
17impl NetItem {
18    pub fn build(&self, nets: Vec<Net>, config: Value) -> rd_interface::Result<Net> {
19        (self.factory)(nets, config)
20    }
21}
22
23impl ServerItem {
24    pub fn build(&self, listen_net: Net, net: Net, config: Value) -> rd_interface::Result<Server> {
25        (self.factory)(vec![listen_net, net], config)
26    }
27}
28
29pub struct Registry {
30    pub net: HashMap<String, NetItem>,
31    pub server: HashMap<String, ServerItem>,
32}
33
34impl fmt::Debug for NetItem {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.debug_struct("NetItem")
37            .field("plugin_name", &self.plugin_name)
38            .finish()
39    }
40}
41
42impl fmt::Debug for ServerItem {
43    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
44        f.debug_struct("ServerItem")
45            .field("plugin_name", &self.plugin_name)
46            .finish()
47    }
48}
49
50impl fmt::Display for Registry {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        writeln!(f, "Net")?;
53        for (k, v) in self.net.iter() {
54            writeln!(f, "\t{}: {}", k, v.plugin_name)?;
55        }
56        writeln!(f, "Server")?;
57        for (k, v) in self.server.iter() {
58            writeln!(f, "\t{}: {}", k, v.plugin_name)?;
59        }
60        Ok(())
61    }
62}
63
64impl Registry {
65    pub fn new() -> Registry {
66        Registry {
67            net: HashMap::new(),
68            server: HashMap::new(),
69        }
70    }
71    pub fn init_with_registry(
72        &mut self,
73        name: impl Into<String>,
74        init: impl Fn(&mut rd_interface::Registry) -> rd_interface::Result<()>,
75    ) -> rd_interface::Result<()> {
76        let mut r = rd_interface::Registry::new();
77        init(&mut r)?;
78        self.add_registry(name.into(), r);
79        Ok(())
80    }
81    fn add_registry(&mut self, plugin_name: String, registry: rd_interface::Registry) {
82        for (k, v) in registry.net {
83            self.net.insert(
84                k,
85                NetItem {
86                    plugin_name: plugin_name.clone(),
87                    factory: v,
88                },
89            );
90        }
91        for (k, v) in registry.server {
92            self.server.insert(
93                k,
94                ServerItem {
95                    plugin_name: plugin_name.clone(),
96                    factory: v,
97                },
98            );
99        }
100    }
101    pub fn get_net(&self, net_type: &str) -> Result<&NetItem> {
102        self.net
103            .get(net_type)
104            .ok_or(anyhow!("Net type is not loaded: {}", net_type))
105    }
106    pub fn get_server(&self, server_type: &str) -> Result<&ServerItem> {
107        self.server
108            .get(server_type)
109            .ok_or(anyhow!("Server type is not loaded: {}", server_type))
110    }
111}