rd_interface/
registry.rs

1use std::{collections::HashMap, fmt};
2
3use crate::{INet, IServer, IntoDyn, Net, Result, Server};
4use serde::de::DeserializeOwned;
5use serde_json::Value;
6
7pub type FromConfig<T> = Box<dyn Fn(Vec<Net>, Value) -> Result<T>>;
8
9#[derive(Debug, Default, serde_derive::Deserialize)]
10pub struct EmptyConfig(Value);
11
12pub struct Registry {
13    pub net: HashMap<String, FromConfig<Net>>,
14    pub server: HashMap<String, FromConfig<Server>>,
15}
16
17impl fmt::Debug for Registry {
18    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19        f.debug_struct("Registry")
20            .field("net", &self.net.keys())
21            .field("server", &self.server.keys())
22            .finish()
23    }
24}
25
26impl Registry {
27    pub fn new() -> Registry {
28        Registry {
29            net: HashMap::new(),
30            server: HashMap::new(),
31        }
32    }
33    pub fn add_net<N: NetFactory>(&mut self) {
34        self.net.insert(N::NAME.into(), N::into_dyn());
35    }
36    pub fn add_server<S: ServerFactory>(&mut self) {
37        self.server.insert(S::NAME.into(), S::into_dyn());
38    }
39}
40
41pub trait NetFactory {
42    const NAME: &'static str;
43    type Config: DeserializeOwned;
44    type Net: INet + Sized + 'static;
45
46    fn new(nets: Vec<Net>, config: Self::Config) -> Result<Self::Net>;
47    fn into_dyn() -> FromConfig<Net> {
48        Box::new(move |nets, cfg| {
49            serde_json::from_value(cfg)
50                .map_err(Into::<crate::Error>::into)
51                .and_then(|cfg| Self::new(nets, cfg))
52                .map(|n| n.into_dyn())
53        })
54    }
55}
56
57pub trait ServerFactory {
58    const NAME: &'static str;
59    type Config: DeserializeOwned;
60    type Server: IServer + Sized + 'static;
61
62    fn new(listen_net: Net, net: Net, config: Self::Config) -> Result<Self::Server>;
63    fn into_dyn() -> FromConfig<Server> {
64        Box::new(move |mut nets, cfg| {
65            serde_json::from_value(cfg)
66                .map_err(Into::<crate::Error>::into)
67                .and_then(|cfg| {
68                    if nets.len() != 2 {
69                        return Err(crate::Error::Other(
70                            "Server must have listen_net and net".to_string().into(),
71                        ));
72                    }
73                    let listen_net = nets.remove(0);
74                    let net = nets.remove(0);
75
76                    Self::new(listen_net, net, cfg)
77                })
78                .map(|n| n.into_dyn())
79        })
80    }
81}