· 6 years ago · Mar 12, 2019, 02:14 PM
1#[cfg(test)]
2mod tests;
3
4use std::convert::From;
5
6use num_cpus;
7use rand::{self, Rng};
8use rocket::{
9 self,
10 config::{Environment, LoggingLevel},
11};
12
13const DEFAULT_SECRETS_PATH: &str = "./secrets";
14const DEFAULT_SERVER_ADDRESS: &str = "0.0.0.0";
15const DEFAULT_SERVER_PORT: u16 = 8000;
16const DEFAULT_KEEP_ALIVE: u32 = 5;
17const DEFAULT_ENVIRONMENT: &str = "development";
18const DEFAULT_LOGGING_LEVEL: &str = "normal";
19
20#[derive(Debug)]
21pub struct Config<'a> {
22 pub secrets_path: String,
23 pub pepper: String,
24
25 pub environment: &'a str,
26 pub log_level: &'a str,
27 pub address: &'a str,
28 pub port: u16,
29 pub keep_alive: u32,
30 pub workers: u16,
31 pub secret_key: String,
32}
33
34fn gen_random_base64_string(length: usize) -> String {
35 let random_string: String = rand::thread_rng()
36 .sample_iter(&rand::distributions::Alphanumeric)
37 .take(length)
38 .collect();
39
40 base64::encode(&random_string)
41}
42
43impl<'a> Default for Config<'a> {
44 fn default() -> Self {
45 Self {
46 secrets_path: String::from(DEFAULT_SECRETS_PATH),
47 pepper: String::new(),
48
49 environment: DEFAULT_ENVIRONMENT,
50 log_level: DEFAULT_LOGGING_LEVEL,
51 keep_alive: DEFAULT_KEEP_ALIVE,
52 address: DEFAULT_SERVER_ADDRESS,
53 port: DEFAULT_SERVER_PORT,
54 workers: (num_cpus::get() * 2) as u16,
55 secret_key: gen_random_base64_string(32),
56 }
57 }
58}
59
60impl<'a> Config<'a> {
61 pub fn new() -> Self {
62 Default::default()
63 }
64
65 fn set_environment_from_option_str_maybe(&mut self, env: Option<&str>) {
66 if let Some(env) = env {
67 match env {
68 "development" | "dev" => { self.environment = "development"; }
69 "production" | "prod" => { self.environment = "production"; }
70 "staging" | "stag" => { self.environment = "staging"; }
71 _ => {}
72 }
73 }
74 }
75
76 fn set_port_from_option_str_maybe(&mut self, port: Option<&str>) {
77 if let Some(port) = port {
78 if let Ok(port) = port.parse::<u16>() {
79 self.port = port;
80 }
81 }
82 }
83
84 fn set_log_level_from_option_str_maybe(&mut self, log_level: Option<&str>) {
85 if let Some(log_level) = log_level {
86 match log_level.to_lowercase().as_str() {
87 "off" | "0" | "none" => { self.log_level = "off"; }
88 "normal" | "1" => { self.log_level = "normal"; }
89 "critical" | "2" => { self.log_level = "critical"; }
90 "debug" | "3" | "debugging" => { self.log_level = "debug"; }
91 _ => {}
92 }
93 }
94 }
95
96 fn set_secrets_path_from_option_str_maybe(&mut self, secrets_path: Option<&str>) {
97 if let Some(secrets_path) = secrets_path {
98 self.secrets_path = secrets_path.to_string();
99 }
100 }
101
102 fn set_pepper_from_option_str_maybe(&mut self, pepper: Option<&str>) {
103 if let Some(pepper) = pepper {
104 self.pepper = pepper.to_string();
105 }
106 }
107
108 fn set_keep_alive_from_option_str_maybe(&mut self, keep_alive: Option<&str>) {
109 if let Some(keep_alive) = keep_alive {
110 if let Ok(n) = keep_alive.parse::<u32>() {
111 self.keep_alive = n;
112 }
113 }
114 }
115
116 fn set_workers_from_option_str_maybe(&mut self, workers: Option<&str>) {
117 if let Some(workers) = workers {
118 if let Ok(n) = workers.parse::<u16>() {
119 self.workers = n;
120 }
121 }
122 }
123}
124
125impl<'a> From<&Config<'a>> for rocket::Config {
126 fn from(c: &Config<'a>) -> Self {
127 let log_level = match c.log_level {
128 "off" => LoggingLevel::Off,
129 "debug" => LoggingLevel::Debug,
130 "critical" => LoggingLevel::Critical,
131 "normal" | _ => LoggingLevel::Normal,
132 };
133
134 let environment = match c.environment {
135 "production" => Environment::Production,
136 "staging" => Environment::Staging,
137 "development" | _ => Environment::Development,
138 };
139
140 Self::build(environment)
141 .address(c.address.clone())
142 .port(c.port)
143 .workers(c.workers)
144 .secret_key(c.secret_key.clone())
145 .log_level(log_level)
146 .keep_alive(c.keep_alive)
147 .unwrap()
148 }
149}
150
151impl<'a> From<&clap::ArgMatches<'a>> for Config<'a> {
152 fn from(matches: &clap::ArgMatches) -> Self {
153 let mut config = Self::new();
154
155 config.set_environment_from_option_str_maybe(matches.value_of("environment"));
156 config.set_port_from_option_str_maybe(matches.value_of("port"));
157 config.set_log_level_from_option_str_maybe(matches.value_of("log-level"));
158 config.set_secrets_path_from_option_str_maybe(matches.value_of("secrets-path"));
159 config.set_pepper_from_option_str_maybe(matches.value_of("pepper"));
160 config.set_keep_alive_from_option_str_maybe(matches.value_of("keep-alive"));
161 config.set_workers_from_option_str_maybe(matches.value_of("workers"));
162
163 println!("config: {:?}", &config);
164
165 config
166 }
167}