Библиотека config для управления конфигурацией в Rust
При разработке приложений на Rust важной задачей является гибкое управление настройками. Библиотека config (крейт config) предоставляет мощный и удобный способ работы с конфигурационными файлами, переменными окружения и встроенными значениями. Она поддерживает форматы TOML, JSON, YAML, HJSON, INI и позволяет объединять настройки из нескольких источников с приоритетами.
Установка
Добавьте зависимость в Cargo.toml:
[dependencies]
config = "0.14"
serde = { version = "1.0", features = ["derive"] }
Базовое использование
Создадим простой конфигурационный файл Settings.toml:
[server]
host = "127.0.0.1"
port = 8080
[database]
url = "postgres://user:pass@localhost/mydb"
pool_size = 10
Теперь загрузим его в Rust-приложение:
use config::{Config, File, Environment};
use serde::Deserialize;
#[derive(Debug, Deserialize)]
struct ServerConfig {
host: String,
port: u16,
}
#[derive(Debug, Deserialize)]
struct DatabaseConfig {
url: String,
pool_size: u32,
}
#[derive(Debug, Deserialize)]
struct AppConfig {
server: ServerConfig,
database: DatabaseConfig,
}
fn main() -> Result<(), config::ConfigError> {
let settings = Config::builder()
.add_source(File::with_name("Settings"))
.add_source(Environment::with_prefix("APP"))
.build()?;
let app_config: AppConfig = settings.try_deserialize()?;
println!("Сервер: {}:{}", app_config.server.host, app_config.server.port);
println!("База данных: {}", app_config.database.url);
Ok(())
}
Поддержка нескольких форматов
Библиотека автоматически определяет формат по расширению файла. Пример с JSON:
let settings = Config::builder()
.add_source(File::with_name("config.json"))
.add_source(File::with_name("override.yaml").required(false))
.build()?;
Переменные окружения
Используйте префикс для переменных окружения, чтобы переопределять настройки без изменения файлов:
// Запуск: APP_SERVER__PORT=9090 cargo run
let settings = Config::builder()
.add_source(File::with_name("Settings"))
.add_source(Environment::with_prefix("APP").separator("__"))
.build()?;
Вложенные настройки и массивы
Поддерживаются иерархические структуры:
#[derive(Debug, Deserialize)]
struct AppConfig {
features: Vec<String>,
logging: LoggingConfig,
}
#[derive(Debug, Deserialize)]
struct LoggingConfig {
level: String,
file: Option<String>,
}
Пример TOML с массивами:
features = ["auth", "caching", "metrics"]
[logging]
level = "info"
file = "/var/log/app.log"
Объединение конфигураций
Библиотека позволяет накладывать настройки из разных источников. Поздние источники имеют более высокий приоритет:
let settings = Config::builder()
.add_source(File::with_name("default")) // базовые настройки
.add_source(File::with_name("production").required(false)) // продакшен
.add_source(Environment::with_prefix("APP")) // переменные окружения
.build()?;
Обработка ошибок и значения по умолчанию
Используйте get() для получения отдельных значений с fallback:
let port: u16 = settings.get("server.port").unwrap_or(8080);
let debug: bool = settings.get("debug").unwrap_or(false);
Динамический доступ к настройкам
Если структура конфигурации неизвестна заранее, используйте динамический доступ:
let val = settings.get_string("database.url")?;
let timeout = settings.get_int("timeout")?;
let enabled = settings.get_bool("features.analytics")?;
Преимущества использования config
- Гибкость – поддержка 5+ форматов конфигурационных файлов
- Иерархичность – вложенные структуры и массивы
- Приоритетность – наложение настроек из разных источников
- Безопасность типов – десериализация через Serde
- Простота – минимальный boilerplate код
- Переменные окру
Также в библиотеке
Tokio для Rust: полное руководство с примерами
Event Bus и паттерн Observer в Go (Golang): реализация и примеры
Работа с ZIP/архивами в TypeScript: полное руководство по JSZip и adm-zip
Миграции баз данных в Swift: инструменты и практики для iOS/macOS