diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 30 | ||||
-rw-r--r-- | src/model/config.rs | 42 |
2 files changed, 44 insertions, 28 deletions
diff --git a/src/main.rs b/src/main.rs index 74917a9..65d52df 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,7 @@ -use clap::Parser; use hyper::service::{make_service_fn, service_fn}; use hyper::Server; use sqlx::sqlite::SqlitePool; use std::convert::Infallible; -use std::net::SocketAddr; #[macro_use] extern crate log; @@ -22,20 +20,7 @@ mod templates; mod utils; mod validation; -use model::config::Config; - -#[derive(Parser)] -#[clap()] -struct Args { - #[clap(short, long, default_value = "0.0.0.0:3000")] - address: SocketAddr, - - #[clap(short, long, default_value = "config.json")] - config: String, - - #[clap(short, long, default_value = "database.db")] - database: String, -} +use model::config; #[tokio::main] async fn main() { @@ -44,13 +29,10 @@ async fn main() { ) .init(); - let args = Args::parse(); - - let config_str = std::fs::read_to_string(&args.config) - .unwrap_or_else(|_| panic!("{}", format!("Missing {}", args.config))); - let config: Config = serde_json::from_str(&config_str).unwrap(); + let config = config::from_env() + .unwrap_or_else(|err| panic!("Error reading config: {err}")); - let pool = SqlitePool::connect(&format!("sqlite:{}", args.database)) + let pool = SqlitePool::connect(&format!("sqlite:{}", config.db_path)) .await .unwrap(); @@ -78,8 +60,8 @@ async fn main() { } }); - info!("Starting server at {}", args.address); - if let Err(e) = Server::bind(&args.address).serve(make_svc).await { + info!("Starting server at {}", config.socket_address); + if let Err(e) = Server::bind(&config.socket_address).serve(make_svc).await { error!("server error: {}", e); } } diff --git a/src/model/config.rs b/src/model/config.rs index e69b4c4..1fa5bb4 100644 --- a/src/model/config.rs +++ b/src/model/config.rs @@ -1,8 +1,42 @@ -use serde::Deserialize; +use std::env; +use std::net::SocketAddr; +use std::str::FromStr; -#[derive(Clone, Deserialize)] +#[derive(Clone)] pub struct Config { - pub secure_cookies: bool, - pub mock_mails: bool, pub auth_secret: String, + pub db_path: String, + pub mock_mails: bool, + pub secure_cookies: bool, + pub socket_address: SocketAddr, +} + +pub fn from_env() -> Result<Config, String> { + Ok(Config { + auth_secret: read_string("AUTH_SECRET")?, + db_path: read_string("DB_PATH")?, + mock_mails: read_bool("MOCK_MAILS")?, + secure_cookies: read_bool("SECURE_COOKIES")?, + socket_address: read_socket_address("SOCKET_ADDRESS")?, + }) +} + +fn read_socket_address(key: &str) -> Result<SocketAddr, String> { + SocketAddr::from_str(&read_string(key)?).map_err(|err| { + format!("environment variable '{key}' is not a socket address: {err}") + }) +} + +fn read_bool(key: &str) -> Result<bool, String> { + read_string(key).and_then(|v| match v.as_str() { + "true" => Ok(true), + "false" => Ok(false), + _ => Err(format!( + "environment variable '{key}' is not a boolean: '{v}'" + )), + }) +} + +fn read_string(key: &str) -> Result<String, String> { + env::var(key).map_err(|_| format!("missing environment variable '{key}'")) } |