Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Use per-env application settings
Browse files Browse the repository at this point in the history
  • Loading branch information
0rzech committed Feb 22, 2024
1 parent ab2e526 commit 0bfc718
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 9 deletions.
4 changes: 2 additions & 2 deletions configuration.yaml → configuration/base.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
application_host: localhost
application_port: 8000
application:
port: 8000
database:
host: localhost
port: 5432
Expand Down
2 changes: 2 additions & 0 deletions configuration/local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
application:
host: localhost
2 changes: 2 additions & 0 deletions configuration/production.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
application:
host: ::0
54 changes: 48 additions & 6 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,14 @@ use serde::Deserialize;

#[derive(Deserialize)]
pub struct Settings {
pub application: ApplicationSettings,
pub database: DatabaseSettings,
pub application_host: String,
pub application_port: u16,
}

#[derive(Deserialize)]
pub struct ApplicationSettings {
pub host: String,
pub port: u16,
}

#[derive(Deserialize)]
Expand Down Expand Up @@ -38,12 +43,49 @@ impl DatabaseSettings {
}

pub fn get_configuration() -> Result<Settings, config::ConfigError> {
let config_dir = std::env::current_dir()
.and_then(|dir| Ok(dir.join("configuration")))
.expect("Failed to determine the current directory");

let environment: Environment = std::env::var("APP_ENVIRONMENT")
.unwrap_or_else(|_| "local".into())
.try_into()
.expect("Failed to parse app environment");

let env_config = format!("{}.yaml", environment.as_str());

let settings = config::Config::builder()
.add_source(config::File::new(
"configuration.yaml",
config::FileFormat::Yaml,
))
.add_source(config::File::from(config_dir.join("base.yaml")))
.add_source(config::File::from(config_dir.join(env_config)))
.build()?;

settings.try_deserialize()
}

pub enum Environment {
Local,
Production,
}

impl Environment {
fn as_str(&self) -> &'static str {
match self {
Environment::Local => "local",
Environment::Production => "production",
}
}
}

impl TryFrom<String> for Environment {
type Error = String;

fn try_from(s: String) -> Result<Self, Self::Error> {
match s.to_lowercase().as_str() {
"local" => Ok(Environment::Local),
"production" => Ok(Environment::Production),
other => Err(format!(
"{other} is not a supported environment. Use either `local` or `production`."
)),
}
}
}
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async fn main() -> Result<(), std::io::Error> {
init_subscriber(subscriber);

let config = get_configuration().expect("Failed to read configuration");
let address = format!("{}:{}", config.application_host, config.application_port);
let address = format!("{}:{}", config.application.host, config.application.port);

let listener = TcpListener::bind(address)
.await
Expand Down

0 comments on commit 0bfc718

Please sign in to comment.