summaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-04-10 20:23:14 -0500
committerToby Vincent <tobyv@tobyvin.dev>2024-04-11 23:51:06 -0500
commit8c56000a3090e0843a1f218a00c3503767658e83 (patch)
treebbcbf4ba4d10468ed8a6e891035ffa4646b77a7c /src/config.rs
parenteb8a597d310d8948d0b5a02911dd2002f00cfb39 (diff)
wip: more work on jwt handling
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs96
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)
-}