settings_struct

Macro settings_struct 

Source
macro_rules! settings_struct {
    ($name:ty) => { ... };
    (
        $name:ty,
        $CONFIG_DIR_VAR_NAME:expr,
        $config_file:expr,
        load_env = ($prefix:expr, $separator:expr, $list_separator:expr)
    ) => { ... };
}
Expand description

Generates a configuration loader for a struct with file and environment variable support.

This macro creates a complete configuration loading system including:

  • A load() method that reads from config files and environment variables
  • A thread-safe static singleton instance
  • A getter function to access the configuration from anywhere in your app

§Usage

§Basic Usage (with defaults)

use dyson_boot::settings_struct;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
struct AppConfig {
    pub host: String,
    pub port: u16,
}

// Uses default values:
// - Config dir: APP__CONFIG_DIR env var (defaults to ".")
// - Config file: app_config.json
// - Env prefix: APP
// - Env separator: __
// - List separator: ,
settings_struct!(AppConfig);

fn main() {
    let config = get_app_config();
    println!("Host: {}", config.host);
}

§Custom Configuration

use dyson_boot::settings_struct;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
struct DatabaseConfig {
    pub url: String,
    pub max_connections: u32,
}

settings_struct!(
    DatabaseConfig,
    "DB_CONFIG_DIR",       // Environment variable for config directory
    "database.json",       // Config file name
    load_env = (
        "DATABASE",        // Environment variable prefix
        "__",              // Environment variable separator
        ","
    )                       // List separator for array values
)

fn main() {
    let db_config = get_database_config();
    println!("DB URL: {}", db_config.url);
}

§Generated Code

For a struct named AppConfig, the macro generates:

  • impl AppConfig { fn load(config_path: PathBuf) -> anyhow::Result<Self> }
  • A static APP_CONFIG: Lazy<Arc<AppConfig>>
  • A function get_app_config() -> Arc<AppConfig>

§Environment Variables

The macro supports overriding config values via environment variables:

# Override top-level fields
export APP__host=0.0.0.0
export APP__port=3000

# Override nested fields (if using nested structs)
export APP__database__url=postgres://localhost/mydb

§Configuration File Location

The config file path is determined by:

  1. Reading the directory from the specified environment variable (e.g., APP__CONFIG_DIR)
  2. If not set, defaults to current directory (.)
  3. Joins the directory with the config file name

§Panics

The generated code will panic and exit the process if:

  • The configuration file cannot be found
  • The configuration file contains invalid data
  • Required fields are missing

§Requirements

Your configuration struct must:

  • Implement serde::Deserialize and serde::Serialize
  • Have all fields that can be deserialized from the config file format

§Examples

§With Environment Variable Override

use dyson_boot::settings_struct;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
struct ServerConfig {
    pub bind_address: String,
    pub port: u16,
    pub workers: usize,
}

settings_struct!(
    ServerConfig,
    "SERVER_CONFIG_DIR",
    "server.json",
    load_env = ("SERVER",
    "__",
    ",")
);

fn main() {
    // Set environment: export SERVER__port=9000
    let config = get_server_config();
    println!("Server will bind to {}:{}", config.bind_address, config.port);
}

§Multiple Configurations

You can use this macro multiple times for different config structs:

use dyson_boot::settings_struct;
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
struct AppConfig { pub name: String }

#[derive(Debug, Clone, Deserialize, Serialize)]
struct DbConfig { pub url: String }

settings_struct!(AppConfig);
settings_struct!(DbConfig, "DB_CONFIG_DIR", "db.json",load_env = ("DB", "__", ","));

fn main() {
    let app = get_app_config();
    let db = get_db_config();
    println!("App: {}, DB: {}", app.name, db.url);
}