11 releases (7 stable)
Uses new Rust 2024
| 2.2.0 | Feb 20, 2026 |
|---|---|
| 2.1.0 | Feb 20, 2026 |
| 1.1.2 | Feb 19, 2026 |
| 0.1.6 | Feb 17, 2026 |
#1193 in Filesystem
360KB
6.5K
SLoC
cfgmatic-files
Configuration file discovery and reading with multiple format support.
Overview
cfgmatic-files provides a simple, cross-platform way to discover and parse configuration files following platform conventions (via cfgmatic-paths). It supports multiple serialization formats and handles configuration merging with proper priority handling.
Features
- Multiple Formats: TOML, JSON, YAML (see note below)
- Cross-platform: Uses
cfgmatic-pathsfor platform-specific directories - Priority-based Merging: User > Local > System
- Type-safe Parsing: Deserialize directly into your structs
- Flexible Discovery: Find all files or just the first available
YAML Support Notice
LEGACY: The
yamlfeature is considered legacy. Theserde_yamlcrate is deprecated by its author and may be removed in future versions. See: https://github.com/dtolnay/serde-yaml/issues/344
Installation
[dependencies]
cfgmatic-files = "0.1"
Enable features as needed:
[dependencies]
cfgmatic-files = { version = "0.1", features = ["toml", "json"] }
Quick Start
Finding Configuration Files
use cfgmatic_files::FileFinder;
// Find all config files for an application
let files = FileFinder::new("myapp").find()?;
for file in &files {
println!("Found: {} ({:?})", file.path.display(), file.tier);
}
Parsing Configurations
use cfgmatic_files::FileFinder;
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct Config {
timeout: u32,
host: String,
}
let files = FileFinder::new("myapp").find()?;
if let Some(file) = files.first() {
let config: Config = file.parse()?;
println!("Timeout: {}, Host: {}", config.timeout, config.host);
}
Loading and Merging
use cfgmatic_files::load_merged;
use serde::Deserialize;
#[derive(Debug, Deserialize, Default)]
struct Config {
port: u16,
host: String,
}
// Load and merge all config files (User > Local > System)
let config: Config = load_merged("myapp")?;
Finding First Available
use cfgmatic_files::{load_first, FileFinder};
// Load the first available config file
let config: Option<Config> = load_first("myapp")?;
// Or find the file first
let files = FileFinder::new("myapp").find()?;
if let Some(file) = files.first() {
// Use file.path() to access the path
println!("Config file: {}", file.path().display());
}
Configuration Priority
Files are searched and prioritized by tier (highest to lowest):
-
User (
ConfigTier::User): User-specific configs- Unix/Linux:
~/.config/myapp/ - macOS:
~/Library/Application Support/myapp/(GUI apps) - Windows:
%APPDATA%\myapp\
- Unix/Linux:
-
Local (
ConfigTier::Local): Machine-specific configs- Unix/Linux:
/usr/local/etc/myapp/,/etc/myapp/ - macOS:
/Library/Application Support/myapp/ - Windows:
%PROGRAMDATA%\myapp\
- Unix/Linux:
-
System (
ConfigTier::System): System-wide configs- Unix/Linux:
/etc/myapp/,/etc/xdg/myapp/ - Windows:
%PROGRAMDATA%\myapp\
- Unix/Linux:
When merging configurations, higher tiers override values from lower tiers.
Supported Formats
TOML (default)
# config.toml
timeout = 30
host = "localhost"
let files = FileFinder::new("myapp")
.formats(&[Format::Toml])
.find()?;
JSON (default)
{
"timeout": 30,
"host": "localhost"
}
let files = FileFinder::new("myapp")
.formats(&[Format::Json])
.find()?;
YAML (legacy feature)
timeout: 30
host: localhost
let files = FileFinder::new("myapp")
.formats(&[Format::Yaml])
.find()?;
Advanced Usage
Custom Format Selection
use cfgmatic_files::{FileFinder, Format};
// Search for TOML and JSON, preferring TOML
let files = FileFinder::new("myapp")
.formats(&[Format::Toml, Format::Json])
.find()?;
Tier-specific Searching
use cfgmatic_files::{FileFinder, ConfigTier};
// Only search user directories
let files = FileFinder::new("myapp")
.tiers(&[ConfigTier::User])
.find()?;
Merging Custom Types
use cfgmatic_files::{ConfigFiles, Mergeable};
use serde::Deserialize;
#[derive(Debug, Deserialize, Default)]
struct Config {
port: u16,
#[serde(default)]
database: DatabaseConfig,
}
#[derive(Debug, Deserialize, Default)]
struct DatabaseConfig {
url: String,
pool_size: u32,
}
let files = FileFinder::new("myapp").find()?;
let config: Config = files.merge()?;
Examples
# Find and display all config files
cargo run --example find_files
# Load and parse TOML config
cargo run --example load_toml
# Merge multiple config files
cargo run --example merge_configs
Feature Flags
default: Enablestomlandjsonfeaturestoml: TOML format support (viatomlcrate)json: JSON format support (viaserde_json)yaml: YAML format support (viaserde_yaml, legacy)async: Async support viatokio
Relationship to cfgmatic
This crate is part of the cfgmatic configuration framework:
- cfgmatic-paths: Platform-specific path discovery
- cfgmatic-files: File discovery and parsing (this crate)
- cfgmatic: High-level API with environment variables and validation
License
This project is licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please see CONTRIBUTING.md for details.
Dependencies
~0.9–4.5MB
~64K SLoC