diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2024-04-10 20:23:14 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2024-04-11 23:51:06 -0500 |
commit | 8c56000a3090e0843a1f218a00c3503767658e83 (patch) | |
tree | bbcbf4ba4d10468ed8a6e891035ffa4646b77a7c /src/config.rs | |
parent | eb8a597d310d8948d0b5a02911dd2002f00cfb39 (diff) |
wip: more work on jwt handling
Diffstat (limited to 'src/config.rs')
-rw-r--r-- | src/config.rs | 96 |
1 files changed, 46 insertions, 50 deletions
diff --git a/src/config.rs b/src/config.rs index d36b8fd..09ec997 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,23 +1,34 @@ -use std::{net::SocketAddr, sync::Arc}; +use std::net::SocketAddr; -use axum::Router; use serde::{Deserialize, Serialize}; -use tokio::net::TcpListener; -use unnamed_server::{state::AppState, Error}; +use unnamed_server::Error; -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone)] pub struct Config { - listen_addr: Option<SocketAddr>, - jwt_secret: Option<String>, - database_url: Option<String>, + pub listen_addr: SocketAddr, + pub jwt_secret: String, + pub database_url: String, } impl Config { - pub fn new() -> Self { - Self::default() + pub fn builder() -> ConfigBuilder { + ConfigBuilder::default() } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ConfigBuilder { + listen_addr: Option<String>, + jwt_secret: Option<String>, + database_url: Option<String>, +} + +impl ConfigBuilder { + pub fn file(self) -> Result<Self, Error> { + let file = std::env::args() + .nth(1) + .unwrap_or("/etc/unnamed_server.toml".to_string()); - pub fn file<P: AsRef<std::path::Path>>(self, file: P) -> Result<Self, Error> { match std::fs::read_to_string(file) { Ok(s) => Ok(self.merge(toml::from_str(&s)?)), Err(err) => { @@ -27,33 +38,14 @@ impl Config { } } - pub fn env(self, prefix: &str) -> Result<Self, Error> { - Ok(self.merge(Self { - listen_addr: std::env::var(format!("{prefix}LISTEN_ADDR")) - .ok() - .and_then(|v| v.parse().ok()), - jwt_secret: std::env::var(format!("{prefix}JWT_SECRET")).ok(), - database_url: std::env::var(format!("{prefix}DATABASE_URL")).ok(), - })) - } + pub fn env(self) -> Self { + let _ = dotenvy::dotenv(); - pub async fn build(self) -> Result<(TcpListener, Router), Error> { - macro_rules! try_extract { - ($($i:ident),+) => { - $(let Some($i) = self.$i else { - return Err(Error::Config(format!("Missing value: {}", stringify!($i)))) - };)+ - }; - } - - try_extract!(listen_addr, jwt_secret, database_url); - - let listener = TcpListener::bind(listen_addr).await?; - let pool = init_db(&database_url).await?; - let app_state = Arc::new(AppState { pool, jwt_secret }); - let app = unnamed_server::init_router(app_state); - - Ok((listener, app)) + self.merge(Self { + listen_addr: std::env::var("LISTEN_ADDR").ok(), + jwt_secret: std::env::var("JWT_SECRET").ok(), + database_url: std::env::var("DATABASE_URL").ok(), + }) } /// Merge self with other, overwriting any existing values on self with other's. @@ -64,25 +56,29 @@ impl Config { database_url: other.database_url.or(self.database_url), } } + + pub fn build(self) -> Result<Config, Error> { + Ok(Config { + listen_addr: self + .listen_addr + .and_then(|s| s.parse().ok()) + .ok_or_else(|| Error::Config("listen_addr".to_string()))?, + jwt_secret: self + .jwt_secret + .ok_or_else(|| Error::Config("jwt_secret".to_string()))?, + database_url: self + .database_url + .ok_or_else(|| Error::Config("database_url".to_string()))?, + }) + } } -impl Default for Config { +impl Default for ConfigBuilder { fn default() -> Self { Self { - listen_addr: Some(SocketAddr::from(([127, 0, 0, 1], 30000))), + listen_addr: Some("127.0.0.1:30000".to_string()), jwt_secret: None, database_url: None, } } } - -async fn init_db(uri: &str) -> Result<sqlx::Pool<sqlx::Postgres>, Error> { - let pool = sqlx::postgres::PgPoolOptions::new() - .max_connections(10) - .connect(uri) - .await?; - - sqlx::migrate!().run(&pool).await?; - - Ok(pool) -} |