Skip to content
/ cruct Public

Lightweight structured configuration loader without serde, supporting TOML, JSON, and YAML formats for easy and flexible configuration management.

License

Unknown, GPL-3.0 licenses found

Licenses found

Unknown
LICENSE
GPL-3.0
GPLv3-LICENSE
Notifications You must be signed in to change notification settings

FlakySL/cruct

cruct-readme

Crates.io Docs.rs License Downloads Codecov tests Discord

A procedural macro for loading configuration files into Rust structs with compile‑time validation and type safety.

Table of Contents 📖

Features 👀

  • Multi‑format support: TOML, YAML, JSON (via Cargo feature flags)
  • Merge & override: CLI args, environment variables, config files, defaults
  • Compile‑time safety: Missing or mismatched fields become compile or runtime errors
  • Nested structures: Automatically derive for nested custom types

Installation 📦

Add to your Cargo.toml:

[dependencies]
cruct = "1.0.0"

Enable only the formats you need:

[dependencies.cruct]
version = "1.0.0"
default-features = false
features = ["toml", "json"]  # only TOML and JSON support

Basic Usage 🔍

Annotate your config‐struct with #[cruct], pointing at one or more sources:

use cruct::cruct;

#[cruct(load_config(path = "config/settings.toml"))]
struct AppConfig {
    #[field(default = 8080)]
    http_port: u16,
    database_url: String,
}

fn main() -> Result<(), cruct_shared::ParserError> {
    let cfg = AppConfig::loader()
        .with_config()
        .load()?;
    println!("Listening on port {}", cfg.http_port);
    Ok(())
}

Use‑Case: Environment‑Variable Override 💡

Often you want a default in your file, but allow ops to override via env vars. For example, given tests/fixtures/test_config.toml:

http_port = 8080

You can override http_port at runtime:

use cruct::cruct;

#[cruct(load_config(path = "tests/fixtures/test_config.toml"))]
#[derive(Debug, PartialEq)]
struct TestEnv {
    #[field(env_override = "TEST_HTTP_PORT")]
    http_port: u16,
}

fn main() {
    // Simulate setting the env var:
    unsafe { std::env::set_var("TEST_HTTP_PORT", "9999"); }

    let config = TestEnv::loader()
        .with_config()
        .load()
        .unwrap();

    assert_eq!(config.http_port, 9999);
    println!("Overridden port: {}", config.http_port);
}

This pattern is drawn directly from our end‑to‑end tests.

Advanced 🥷

  • Multiple files & priority: Chain load_config calls with explicit priority
  • Case‑insensitive keys: Use #[field(name = "HTTP_PORT", insensitive = true)]
  • Default values: Supply literals, expressions, or functions for default

See the full API docs for details on all options.

License 📜

This repository is dual licensed, TLDR. If your repository is open source, the library is free of use, otherwise contact licensing@flaky.es for a custom license for your use case.

For more information read the license file.

About

Lightweight structured configuration loader without serde, supporting TOML, JSON, and YAML formats for easy and flexible configuration management.

Topics

Resources

License

Unknown, GPL-3.0 licenses found

Licenses found

Unknown
LICENSE
GPL-3.0
GPLv3-LICENSE

Code of conduct

Security policy

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •