1c9a7c0b05
Co-authored-by: Michael Neale <michael.neale@gmail.com> Co-authored-by: Wendy Tang <wendytang@squareup.com> Co-authored-by: Jarrod Sibbison <72240382+jsibbison-square@users.noreply.github.com> Co-authored-by: Alex Hancock <alex.hancock@example.com> Co-authored-by: Alex Hancock <alexhancock@block.xyz> Co-authored-by: Lifei Zhou <lifei@squareup.com> Co-authored-by: Wes <141185334+wesrblock@users.noreply.github.com> Co-authored-by: Max Novich <maksymstepanenko1990@gmail.com> Co-authored-by: Zaki Ali <zaki@squareup.com> Co-authored-by: Salman Mohammed <smohammed@squareup.com> Co-authored-by: Kalvin C <kalvinnchau@users.noreply.github.com> Co-authored-by: Alec Thomas <alec@swapoff.org> Co-authored-by: lily-de <119957291+lily-de@users.noreply.github.com> Co-authored-by: kalvinnchau <kalvin@block.xyz> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Rizel Scarlett <rizel@squareup.com> Co-authored-by: bwrage <bwrage@squareup.com> Co-authored-by: Kalvin Chau <kalvin@squareup.com> Co-authored-by: Alice Hau <110418948+ahau-square@users.noreply.github.com> Co-authored-by: Alistair Gray <ajgray@stripe.com> Co-authored-by: Nahiyan Khan <nahiyan.khan@gmail.com> Co-authored-by: Alex Hancock <alexhancock@squareup.com> Co-authored-by: Nahiyan Khan <nahiyan@squareup.com> Co-authored-by: marcelle <1852848+laanak08@users.noreply.github.com> Co-authored-by: Yingjie He <yingjiehe@block.xyz> Co-authored-by: Yingjie He <yingjiehe@squareup.com> Co-authored-by: Lily Delalande <ldelalande@block.xyz> Co-authored-by: Adewale Abati <acekyd01@gmail.com> Co-authored-by: Ebony Louis <ebony774@gmail.com> Co-authored-by: Angie Jones <jones.angie@gmail.com> Co-authored-by: Ebony Louis <55366651+EbonyLouis@users.noreply.github.com>
91 lines
2.7 KiB
Rust
91 lines
2.7 KiB
Rust
use crate::error::{to_env_var, ConfigError};
|
|
use config::{Config, Environment};
|
|
use serde::Deserialize;
|
|
use std::net::SocketAddr;
|
|
|
|
#[derive(Debug, Default, Deserialize)]
|
|
pub struct Settings {
|
|
#[serde(default = "default_host")]
|
|
pub host: String,
|
|
#[serde(default = "default_port")]
|
|
pub port: u16,
|
|
}
|
|
|
|
impl Settings {
|
|
pub fn socket_addr(&self) -> SocketAddr {
|
|
format!("{}:{}", self.host, self.port)
|
|
.parse()
|
|
.expect("Failed to parse socket address")
|
|
}
|
|
|
|
pub fn new() -> Result<Self, ConfigError> {
|
|
Self::load_and_validate()
|
|
}
|
|
|
|
fn load_and_validate() -> Result<Self, ConfigError> {
|
|
// Start with default configuration
|
|
let config = Config::builder()
|
|
// Server defaults
|
|
.set_default("host", default_host())?
|
|
.set_default("port", default_port())?
|
|
// Layer on the environment variables
|
|
.add_source(
|
|
Environment::with_prefix("GOOSE")
|
|
.prefix_separator("_")
|
|
.separator("__")
|
|
.try_parsing(true),
|
|
)
|
|
.build()?;
|
|
|
|
// Try to deserialize the configuration
|
|
let result: Result<Self, config::ConfigError> = config.try_deserialize();
|
|
|
|
// Handle missing field errors specially
|
|
match result {
|
|
Ok(settings) => Ok(settings),
|
|
Err(err) => {
|
|
tracing::debug!("Configuration error: {:?}", &err);
|
|
|
|
// Handle both NotFound and missing field message variants
|
|
let error_str = err.to_string();
|
|
if error_str.starts_with("missing field") {
|
|
// Extract field name from error message "missing field `type`"
|
|
let field = error_str
|
|
.trim_start_matches("missing field `")
|
|
.trim_end_matches("`");
|
|
let env_var = to_env_var(field);
|
|
Err(ConfigError::MissingEnvVar { env_var })
|
|
} else if let config::ConfigError::NotFound(field) = &err {
|
|
let env_var = to_env_var(field);
|
|
Err(ConfigError::MissingEnvVar { env_var })
|
|
} else {
|
|
Err(ConfigError::Other(err))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn default_host() -> String {
|
|
"127.0.0.1".to_string()
|
|
}
|
|
|
|
fn default_port() -> u16 {
|
|
3000
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_socket_addr_conversion() {
|
|
let server_settings = Settings {
|
|
host: "127.0.0.1".to_string(),
|
|
port: 3000,
|
|
};
|
|
let addr = server_settings.socket_addr();
|
|
assert_eq!(addr.to_string(), "127.0.0.1:3000");
|
|
}
|
|
}
|