Skip to main content

Crate cfg_rs

Crate cfg_rs 

Source
Expand description

§cfg-rs: A Configuration Library for Rust Applications

Crates.io Crates.io Documentation dependency status License Actions Status Minimum supported Rust version

cfg-rs is a lightweight, flexible configuration loader for Rust applications. It composes multiple sources (files, env, inline maps, random, etc.), supports live refresh, placeholder expansion, and derive-based typed configs — all without a serde dependency.

See the examples directory for end-to-end demos.

§Documentation map

If you are new to this crate, read in this order:

  1. Quick start in this README
  2. Examples for end-to-end usage patterns
  3. docs.rs API reference for type-level details
  4. CONTRIBUTING.md for contribution and documentation standards

§Features

  • Single call to load typed config: see Configuration::get
  • Derive your config types: see FromConfig
  • Default values via field attributes: see field attributes
  • Placeholder expansion like ${cfg.key}: see ConfigValue
  • Random values under the rand feature (e.g. configuration.get::<u8>("random.u8"))
  • Refreshable values via RefValue and refreshable Configuration
  • Field-level validation via #[validate(...)] rules (range, length, not_empty, custom, regex)
  • Pluggable sources with clear priority: see register_source1
  • No serde dependency

§Supported formats and feature flags

Built-in file parsers (enable via Cargo features):

FeatureFile extensionsNotes
toml.toml, .tmlTyped values and nested tables
yaml.yaml, .ymlFriendly for hand-written configs
json.jsonGood for generated or machine-edited config
ini.iniFlat/simple legacy formats

Other useful features:

  • validate (built-in): supports #[validate(range)], #[validate(length)], #[validate(not_empty)], and #[validate(custom = ...)]
  • rand: random value provider (e.g. random.u8, random.string)
  • log: minimal logging integration for value parsing
  • coarsetime: coarse time helpers for time-related values
  • regex: enables #[validate(regex = ...)] validator

Tip: in application crates, define your own feature aliases (e.g. full-config = ["cfg-rs/full"]) so downstream users can enable capabilities consistently.

§Installation

Add to your Cargo.toml with the features you need:

[dependencies]
cfg-rs = { version = "^1.0", features = ["toml"] }

For a batteries-included setup, use the convenience feature set:

cfg-rs = { version = "^1.0", features = ["full"] }

§Example guide

This README organizes examples into two tracks:

  1. Derive-first typed config (#[config(...)] + #[validate(...)])
  2. Source composition (from simple to complex)

Use derive for app-facing config structs. This single example covers:

  • #[config(name = "...")]
  • #[config(default = ...)]
  • Placeholder defaults via ${...} in values
  • #[validate(...)]
#[derive(Debug, cfg_rs::FromConfig)]
#[config(prefix = "app")]
struct AppCfg {
    #[config(name = "service_name", default = "demo")]
    #[validate(length(min = 1, max = 32))]
    name: String,

    #[config(default = "${server.host:127.0.0.1}")]
    host: String,

    #[config(default = "${server.port:8080}")]
    #[validate(range(min = 1, max = 65535))]
    port: u16,

    #[config(default = 4)]
    #[validate(custom = check_workers)]
    workers: usize,
}

fn check_workers(v: &usize) -> Result<(), String> {
    if *v == 0 {
        return Err("workers must be > 0".to_string());
    }
    Ok(())
}

let cfg: AppCfg = cfg_rs::from_static_map!(AppCfg, {
    "service_name" => "api",
    "server.host" => "0.0.0.0",
});
assert_eq!(cfg.name, "api");
assert_eq!(cfg.host, "0.0.0.0");
assert_eq!(cfg.port, 8080);

Notes:

  • Placeholder expressions are value syntax, not a separate derive attribute.
  • Full derive attribute reference: derive.FromConfig
  • Validation rules: range, length, not_empty, custom, regex (feature = regex)

§2) Source composition (simple -> complex)

§a) Simplest: predefined stack
use cfg_rs::*;

let configuration = Configuration::with_predefined().unwrap();
// let port: u16 = configuration.get("app.port").unwrap();
§b) Common: explicit env + file
use cfg_rs::*;

let configuration = Configuration::new()
    .register_prefix_env("APP").unwrap()
    .register_file("./app.toml", true).unwrap();
§c) Advanced: layered sources with deterministic priority
use cfg_rs::*;
init_cargo_env!();

let mut configuration = Configuration::new()
    // Layer 0 (highest): Cargo env source.
    .register_source(init_cargo_env()).unwrap()
    // Layer 1: Inline key-values.
    .register_kv("inline")
        .set("app.name", "demo")
        .finish()
        .unwrap();

// Layer 2: Random values (feature = "rand").
#[cfg(feature = "rand")]
{
    configuration = configuration.register_random().unwrap();
}

// Layer 3: Environment variables with prefix `APP_`.
configuration = configuration.register_prefix_env("APP").unwrap();

// Layer 4 (lowest): File source.
configuration = configuration.register_file("./app.yaml", true).unwrap();

// Optional: merge inline file content.
#[cfg(feature = "toml")]
{
    let toml = inline_source!("app.toml").unwrap();
    configuration = configuration.register_source(toml).unwrap();
}

See register_kv, register_file, register_random, and register_prefix_env.

§Placeholders, randoms, and refresh

  • Placeholder expansion: use ${some.key} inside string values; see ConfigValue
  • Random values: under rand, keys like random.u8, random.string provide per-read randoms
  • Refreshing: Configuration::refresh() re-reads sources that allow refresh; RefValue<T> updates on refresh

§Runnable examples

  • simple: minimal setup (full feature set)
  • profile: working with profiles (requires toml)
  • watch: basic file watching and refresh (requires yaml)
  • refresh: manual refresh and RefValue
  • logger: logging integration (requires full)
  • thread_pool, salak, test_suit: larger samples and integrations

https://github.com/leptonyu/cfg-rs/tree/main/examples

§License

MIT © contributors. See LICENSE.

§Minimum supported Rust version

This crate supports Rust 1.85 and newer. Older Rust versions are not guaranteed to compile or be tested.

§Tips and notes

  • Source priority is deterministic: earlier registrations override later ones1
  • This crate intentionally does not depend on serde
  • Docs.rs builds enable all features for a comprehensive reference

  1. Source precedence follows registration order — earlier registrations have higher priority. ↩ 1 2

Modules§

source
Configuration sources module, see the examples for general usage information.
validate
Validation helpers used by the #[validate(...)] field attributes.

Macros§

from_static_map
Test macro to generate config instance from a static map of key-value pairs.
impl_enum
Implement FromConfig for enums.
init_cargo_env
Collect all CARGO_PKG_* env variables, and CARGO_BIN_NAME into configuration.
inline_source
Inline config file in repo, see Supported File Formats.

Structs§

ByteSize
Byte size value in bytes. Use u64 for platform independence.
ConfigContext
Configuration Context.
Configuration
Configuration Instance, See Examples, How to Initialize Configuration for details.
FromStrHolder
Wrapper for all FromStr type.
PredefinedConfigurationBuilder
Predefined Configuration Builder. See init for details.
RefValue
RefValue means reference of value or refreshable value, it holds a value which can be updated when Configuration is refreshed.

Enums§

ConfigError
Configuration Error.
ConfigValue
Config value, ConfigSource use this value to store config properties.

Traits§

FromConfig
Generate config instance from configuration.
FromConfigWithPrefix
Config with prefix. This trait is auto derived by FromConfig.
FromStringValue
Get from string.

Functions§

from_env
Generate config instance from environment variables.
from_map
Generate config instance from a map of key-value pairs.

Type Aliases§

ConfigKey
Config key, ConfigSource use this key to access config properties.

Derive Macros§

FromConfig
Automatic derive FromConfig instance.