]> git.r.bdr.sh - rbdr/olden-mail/blob - src/configuration.rs
Use binstall quick install
[rbdr/olden-mail] / src / configuration.rs
1 //! # Configuration
2 //!
3 //! This module defines the configuration used to initialize both proxies.
4
5 use log::error;
6 use std::env;
7 use std::fmt::Debug;
8 use std::sync::Arc;
9 use thiserror::Error;
10
11 #[derive(Error, Debug)]
12 pub enum Error {
13 #[error("Environment variable {0} not set.")]
14 MissingEnvVar(String),
15 #[error("Failed to parse {0}.")]
16 ParseError(String),
17 }
18
19 /// Configuration for any proxy
20 #[derive(Debug)]
21 pub struct Proxy {
22 pub local_port: u16,
23 pub bind_address: String,
24 pub remote_host: String,
25 pub remote_port: u16,
26 pub protocol: &'static str,
27 }
28
29 /// Aggregated configuration for both proxies, already in a reference counter.
30 pub struct Configuration {
31 pub imap_configuration: Arc<Proxy>,
32 pub smtp_configuration: Arc<Proxy>,
33 }
34
35 impl Configuration {
36 /// Creates a new configuration object by reading the environment
37 /// variables. Exits if the right ones aren't found.
38 pub fn new() -> Result<Self, Error> {
39 Ok(Configuration {
40 imap_configuration: Arc::new(Proxy {
41 local_port: get_env_number("LOCAL_IMAP_PORT", 143)?,
42 bind_address: get_env_var("LOCAL_IMAP_BIND_ADDRESS", Some("0.0.0.0".to_string()))?,
43 remote_host: get_env_var("REMOTE_IMAP_HOST", None)?,
44 remote_port: get_env_number("REMOTE_IMAP_PORT", 993)?,
45 protocol: "IMAP",
46 }),
47 smtp_configuration: Arc::new(Proxy {
48 local_port: get_env_number("LOCAL_SMTP_PORT", 25)?,
49 bind_address: get_env_var("LOCAL_SMTP_BIND_ADDRESS", Some("0.0.0.0".to_string()))?,
50 remote_host: get_env_var("REMOTE_SMTP_HOST", None)?,
51 remote_port: get_env_number("REMOTE_SMTP_PORT", 465)?,
52 protocol: "SMTP",
53 }),
54 })
55 }
56 }
57
58 /// Get an environment variable or return an error.
59 fn get_env_var(name: &str, default: Option<String>) -> Result<String, Error> {
60 match env::var(name) {
61 Ok(value) => Ok(value),
62 Err(_) => match default {
63 Some(default_value) => Ok(default_value),
64 None => Err(Error::MissingEnvVar(name.to_string())),
65 },
66 }
67 }
68
69 /// Get an environment variable and parse it as a number. Return a default
70 /// if not set.
71 fn get_env_number(name: &str, default: u16) -> Result<u16, Error> {
72 match env::var(name) {
73 Ok(value) => value
74 .parse()
75 .map_err(|_| Error::ParseError(name.to_string())),
76 Err(_) => Ok(default),
77 }
78 }