cruct

Crates.iocruct
lib.rscruct
version1.0.0
created_at2025-07-11 21:52:37.881231+00
updated_at2025-07-11 21:52:37.881231+00
descriptionA procedural macro for loading configuration files into Rust structs with compile‑time validation and type safety.
homepage
repositoryhttps://github.com/FlakySL/cruct
max_upload_size
id1748523
size38,556
Chiko (chikof)

documentation

README

cruct-readme

Crates.io Docs.rs License Downloads Codecov tests Discord


Cruct

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.

Commit count: 0

cargo fmt