8 unstable releases (3 breaking)
new 0.5.0 | May 5, 2025 |
---|---|
0.4.0 | Mar 20, 2025 |
0.3.4 | Mar 14, 2025 |
0.3.2 | Nov 12, 2024 |
0.1.0 | Oct 15, 2024 |
#332 in Configuration
103 downloads per month
17KB
238 lines
config_tools
config_tools
is a lightweight, ergonomic Rust library for working with INI-style configuration files. It offers:
- A builder pattern for programmatic config creation
- Macros for concise default declarations
- Optional typed section parsing using
FromSection
- Graceful fallbacks with
load_or_default_outcome
serde
support for full serialization and deserialization
It is built on top of rust-ini
and designed for developer ergonomics first.
Quickstart
use config_tools::{Config, sectioned_defaults};
let outcome = Config::load_or_default_outcome(
"config.ini",
sectioned_defaults! {
{ "debug" => "true" }
["App"] {
"threads" => "4"
}
}
);
if outcome.used_default() {
eprintln!("Using fallback config.");
}
let config = outcome.into_inner();
Manual Configuration
use config_tools::Config;
let config = Config::builder()
.general()
.set("logging", "true")
.set("verbose", "false")
.section("Database")
.set("host", "localhost")
.set("port", "5432")
.build();
Macros for Inline Defaults
use config_tools::{sectioned_defaults, general_defaults, Config};
let sectioned: Config = sectioned_defaults! {
{ "logging" => "true" }
["Server"] {
"host" => "127.0.0.1",
"port" => "8080"
}
};
let general: Config = general_defaults! {
"console" => "true",
"logging" => "true",
};
Loading and Saving Configs
use config_tools::Config;
let config = Config::load("config.ini")?;
config.save("out.ini")?;
You can also handle missing files gracefully:
let default = Config::builder().set("fallback", "true").build();
let config = Config::load_or_default("config.ini", default);
Or check whether defaults were used:
let outcome = Config::load_or_default_outcome("config.ini", Config::default());
if outcome.used_default() {
println!("File not found; using defaults.");
}
let config = outcome.into_inner();
Typed Section Parsing with FromSection
use config_tools::{Config, FromSection};
#[derive(FromSection)]
struct ServerConfig {
host: String,
port: u16,
}
let config = Config::load("config.ini")?;
let server_section = config.section("Server").unwrap();
let server: ServerConfig = ServerConfig::from_section(server_section)?;
Config
API
Config::builder()
: Starts a new builderConfig::load(path)
: Loads from fileConfig::save(path)
: Saves to fileConfig::load_or_default(path, default)
: Uses a fallback if loading failsConfig::load_or_default_outcome(...)
: Same as above, but returnsLoadOutcome
config.get(section, key)
: Returns a value asOption<String>
config.get_as::<T>(...)
: Parses value into a typeconfig.update(...)
: Updates or inserts a key-value pair
LoadOutcome
Returned from load_or_default_outcome
:
LoadOutcome::FromFile(config)
LoadOutcome::FromDefault(config)
Methods:
.into_inner()
: Extract the config.as_ref()
,.as_mut()
: Borrow access.used_default() -> bool
: Did fallback occur?
Macros
sectioned_defaults!
let config = sectioned_defaults! {
{ "logging" => "true" }
["App"] {
"theme" => "dark"
}
};
Supports variables for section names, keys, and values (must be strings). General keys must come first.
general_defaults!
let config = general_defaults! {
"logging" => "true",
"console" => "true"
};
Procedural Macro: #[derive(FromSection)]
Allows typed parsing of section contents:
#[derive(FromSection)]
struct MySettings {
path: String,
enabled: bool,
}
Fields must implement FromStr
.
Dependencies
~1.5–2.3MB
~43K SLoC