qm_server/
config.rs

1use serde::Deserialize;
2use std::sync::Arc;
3
4#[derive(Deserialize)]
5pub struct Config {
6    app_name: Option<Arc<str>>,
7    host: Option<Arc<str>>,
8    port: Option<u16>,
9    #[serde(skip)]
10    address: Option<Arc<str>>,
11}
12
13impl Config {
14    pub fn new() -> envy::Result<Self> {
15        ConfigBuilder::default().build()
16    }
17
18    pub fn builder<'a>() -> ConfigBuilder<'a> {
19        ConfigBuilder::default()
20    }
21
22    pub fn app_name(&self) -> &str {
23        self.app_name.as_deref().unwrap()
24    }
25
26    pub fn address(&self) -> &str {
27        self.address.as_deref().unwrap()
28    }
29
30    pub fn port(&self) -> u16 {
31        self.port.unwrap_or(3000)
32    }
33}
34
35#[derive(Default)]
36pub struct ConfigBuilder<'a> {
37    prefix: Option<&'a str>,
38}
39
40impl<'a> ConfigBuilder<'a> {
41    pub fn with_prefix(mut self, prefix: &'a str) -> Self {
42        self.prefix = Some(prefix);
43        self
44    }
45
46    pub fn build(self) -> envy::Result<Config> {
47        let prefix = self.prefix.unwrap_or("SERVER_");
48        let mut cfg: Config = envy::prefixed(prefix).from_env()?;
49        if cfg.app_name.is_none() {
50            cfg.app_name = Some(Arc::from("quick-microservice"));
51        }
52        let host = cfg.host.as_deref().unwrap_or("127.0.0.1");
53        let port = cfg.port.unwrap_or(3000);
54        cfg.address = Some(Arc::from(format!("{}:{}", host, port)));
55        Ok(cfg)
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    #[test]
62    fn parse_builtin_config_test() -> envy::Result<()> {
63        let cfg = super::Config::builder()
64            .with_prefix("DEFAULT_SERVER_NOT_SET_IN_SHELL_")
65            .build()?;
66        assert_eq!(cfg.address(), "127.0.0.1:3000");
67        Ok(())
68    }
69
70    #[test]
71    fn parse_default_config_test() -> envy::Result<()> {
72        std::env::set_var("SERVER_HOST", "localhost");
73        std::env::set_var("SERVER_PORT", "3000");
74        let cfg = super::Config::new()?;
75        assert_eq!(cfg.address(), "localhost:3000");
76        Ok(())
77    }
78
79    #[test]
80    fn parse_prefixed_config_test() -> envy::Result<()> {
81        std::env::set_var("SERVER_CUSTOM_HOST", "localhost");
82        std::env::set_var("SERVER_CUSTOM_PORT", "3000");
83        let cfg = super::Config::builder()
84            .with_prefix("SERVER_CUSTOM_")
85            .build()?;
86        assert_eq!(cfg.address(), "localhost:3000");
87        Ok(())
88    }
89}