config from env

This commit is contained in:
Robin Appelman 2023-11-25 00:17:14 +01:00
commit 652fd43f36
4 changed files with 56 additions and 3 deletions

12
Cargo.lock generated
View file

@ -1074,6 +1074,7 @@ dependencies = [
"sea-query", "sea-query",
"sea-query-binder", "sea-query-binder",
"serde", "serde",
"serde-env",
"sqlx", "sqlx",
"steam-openid", "steam-openid",
"steamid-ng", "steamid-ng",
@ -3028,6 +3029,17 @@ dependencies = [
"serde_derive", "serde_derive",
] ]
[[package]]
name = "serde-env"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c68119a0846249fd6f4b38561b4b4727dbc4fd9fea074f1253bca7d50440ce58"
dependencies = [
"anyhow",
"log",
"serde",
]
[[package]] [[package]]
name = "serde-wasm-bindgen" name = "serde-wasm-bindgen"
version = "0.3.1" version = "0.3.1"

View file

@ -32,3 +32,4 @@ reqwest = "0.11.16"
rand = "0.8.5" rand = "0.8.5"
demostf-build = { path = "./build", version = "*" } demostf-build = { path = "./build", version = "*" }
include_dir = "0.7.3" include_dir = "0.7.3"
serde-env = "0.1.1"

View file

@ -1,6 +1,7 @@
use crate::Result; use crate::Result;
use config::{Environment, File}; use config::{Environment, File};
use serde::Deserialize; use serde::Deserialize;
use serde_env::from_env;
use sqlx::postgres::PgConnectOptions; use sqlx::postgres::PgConnectOptions;
use sqlx::PgPool; use sqlx::PgPool;
use std::net::IpAddr; use std::net::IpAddr;
@ -22,6 +23,10 @@ impl Config {
Ok(s.try_deserialize()?) Ok(s.try_deserialize()?)
} }
pub fn env() -> Option<Self> {
from_env().ok()
}
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@ -42,7 +47,26 @@ impl DbConfig {
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
#[serde(untagged)] pub struct RawListen {
path: Option<PathBuf>,
address: Option<IpAddr>,
port: Option<u16>,
}
impl TryFrom<RawListen> for Listen {
type Error = &'static str;
fn try_from(value: RawListen) -> std::result::Result<Self, Self::Error> {
match (value.path, value.address, value.port) {
(Some(path), None, None) => Ok(Listen::Socket { path }),
(None, Some(address), Some(port)) => Ok(Listen::Tcp { address, port }),
_ => Err("invalid listen section"),
}
}
}
#[derive(Debug, Deserialize)]
#[serde(try_from = "RawListen")]
pub enum Listen { pub enum Listen {
Socket { path: PathBuf }, Socket { path: PathBuf },
Tcp { address: IpAddr, port: u16 }, Tcp { address: IpAddr, port: u16 },
@ -51,6 +75,16 @@ pub enum Listen {
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct SiteConfig { pub struct SiteConfig {
pub url: String, pub url: String,
#[serde(default = "default_api")]
pub api: String, pub api: String,
#[serde(default = "default_maps")]
pub maps: String, pub maps: String,
} }
fn default_api() -> String {
"https://api.demos.tf/".into()
}
fn default_maps() -> String {
"https://maps.demos.tf/".into()
}

View file

@ -79,8 +79,14 @@ async fn main() -> Result<()> {
.try_init() .try_init()
.expect("Failed to init tracing"); .expect("Failed to init tracing");
let config = args().skip(1).next().expect("no config file provided"); let config = args()
let config = Config::load(&config)?; .skip(1)
.next()
.as_deref()
.map(Config::load)
.transpose()?
.or_else(Config::env)
.expect("no config file or env provided");
let connection = config.database.connect().await?; let connection = config.database.connect().await?;
let session_store = MemoryStore::new(); let session_store = MemoryStore::new();