diff --git a/src/server/config.rs b/src/server/config.rs index 6d0aed7..06f7893 100644 --- a/src/server/config.rs +++ b/src/server/config.rs @@ -1,8 +1,78 @@ use serde::Deserialize; +#[derive(Debug, Clone, Deserialize)] +pub struct DatabaseConfig { + #[serde(flatten)] + connection: DatabaseConnectionConfig, +} + +impl DatabaseConfig { + /// Get the configured database connection URI + pub fn connection_uri(&self) -> String { + self.connection.as_uri() + } +} + +#[derive(Debug, Clone, Deserialize)] +#[serde(untagged)] +enum DatabaseConnectionConfig { + FromUrl { + url: String, + }, + FromParts { + host: String, + port: Option, + database: Option, + username: Option, + password: Option, + }, +} + +impl DatabaseConnectionConfig { + /// Convert this configuration into the Postgres connection URI + pub fn as_uri(&self) -> String { + match self { + Self::FromUrl { url } => url.clone(), + Self::FromParts { + host, + port, + database, + username, + password, + } => { + let mut url = "postgres://".to_string(); + + if let Some(username) = username { + url.push_str(username); + + if let Some(password) = password { + url.push_str(&format!(":{password}")); + } + + url.push('@'); + } + + url.push_str(host); + + if let Some(port) = port { + url.push_str(&format!(":{port}")); + } + + if let Some(database) = database { + url.push_str(&format!("/{database}")); + } + + url + } + } + } +} + #[derive(Debug, Clone, Deserialize)] /// Top-level application configuration -pub struct Config {} +pub struct Config { + pub database: DatabaseConfig, +} /// Parse configuration from the expected files and environment variables pub fn load_config() -> Result {