A layered runtime configuration system for Rust, inspired by the Go figtree package. Supports multiple configuration sources with explicit priority resolution, per-key validators, per-key callbacks, and live mutation tracking via channels.
rusty-figtree/
βββ Cargo.toml # workspace root β ties both crates together
βββ VERSION # single version file for both crates
βββ build.rs # reads VERSION, exposes APP_VERSION at compile time
βββ .gitignore
βββ LICENSE
βββ CHANGELOG.md
βββ figtree/ # primary library crate
β βββ Cargo.toml
β βββ README.md
β βββ src/
β βββ lib.rs
β βββ error.rs
β βββ tree.rs
β βββ fig.rs
β βββ mutation.rs
β βββ priority.rs
β βββ rules.rs
β βββ validators.rs
β βββ callbacks.rs
β βββ sources/
β β βββ mod.rs
β β βββ env.rs
β β βββ cli.rs
β β βββ yaml.rs
β β βββ json.rs
β β βββ ini.rs
β β βββ embedded.rs
β βββ tests/
β βββ tree_test.rs
β βββ validators_test.rs
β βββ priority_test.rs
β βββ sources_test.rs
β βββ callbacks_test.rs
βββ figtree-derive/ # procedural macro crate
βββ Cargo.toml
βββ README.md
βββ src/
βββ lib.rs
This repository is a Cargo workspace containing two crates that are always versioned, built, tested, and published together.
figtree is the library your application depends on at runtime. figtree-derive is the procedural macro crate the Rust compiler consumes at build time to expand the #[derive(Figtree)] decorator. End users never reference figtree-derive directly in their own Cargo.toml β it is re-exported transparently by figtree.
figtree resolves configuration values in a fixed priority order. This order is inspired by PEMDAS β just as multiplication always precedes addition regardless of left-to-right reading, CLI flags always precede environment variables regardless of declaration order.
CLI flags
> Environment Variables
> Configuration Files (in load order)
> Programmatic Store()
> Default Values
The source that wins is the one highest in this hierarchy that has a value defined. A default only speaks when nothing above it does.
Feature What It Enables
------- ---------------
std Standard library support (enabled by default)
env Environment variable source (enabled by default)
yaml YAML config file source via serde_yaml
json JSON config file source via serde_json
ini INI config file source via rust-ini
cli CLI flag source via clap
async Async mutation channel via tokio
embedded Bare metal source support, implies no_std
Both crates share a single VERSION file at the repository root. The build.rs script reads this file at compile time and exposes the version as APP_VERSION. Bumping the version with the bump tool updates both crates atomically.
bump -patch -write
cargo build --release
Apache 2.0