Rust配置管理库config_struct的使用,自动化生成类型安全配置结构与环境变量解析

Rust配置管理库config_struct的使用,自动化生成类型安全配置结构与环境变量解析

注意:该库已废弃

请注意:这个crate已经废弃。请使用它的替代品。

库介绍

这是一个在构建时将配置文件转换为匹配的源文件的库。

使用方法

这个库需要在build.rs文件中使用,因此需要添加到[build-dependencies]中。

[build-dependencies.config_struct]
version = "~0.4.0"
features = ["toml-parsing"]

默认情况下,config_struct是与标记语言无关的,所以需要包含与你的配置文件语言相关的特性。可选特性有:

  1. json-parsing
  2. ron-parsing
  3. toml-parsing
  4. yaml-parsing

构建时使用

在你的build.rs文件中,添加如下代码:

use config_struct::{Error, StructOptions};

fn main() -> Result<(), Error> {
    config_struct::create_config(
        "config.toml",          // 输入配置文件路径
        "src/config.rs",        // 输出Rust文件路径
        &StructOptions::default()) // 使用默认选项
}

支持serde

除非你特意在运行时避免使用serde系列crate,否则建议使用以下选项:

StructOptions {
    serde_support: SerdeSupport::Yes,
    generate_load_fns: true,
    .. my_other_options
}

这将为你的结构体派生SerializeDeserialize trait,并提供方便的load()方法来在运行时读取和解析文件。

完整示例

以下是一个完整的示例,展示如何使用config_struct库来管理配置:

  1. 首先,在Cargo.toml中添加依赖:
[build-dependencies.config_struct]
version = "0.5.1"
features = ["toml-parsing", "serde"]
  1. 创建build.rs文件:
use config_struct::{Error, StructOptions};

fn main() -> Result<(), Error> {
    config_struct::create_config(
        "config.toml",
        "src/config.rs",
        &StructOptions {
            serde_support: config_struct::SerdeSupport::Yes,
            generate_load_fns: true,
            ..StructOptions::default()
        },
    )
}
  1. 创建config.toml配置文件:
app_name = "My App"
port = 8080
debug = true
database_url = "postgres://user:pass@localhost/db"
  1. 在main.rs中使用生成的配置:
mod config; // 导入生成的config模块

fn main() {
    // 在debug模式下从文件加载,在release模式下使用编译时常量
    let config = config::Config::load();
    
    println!("App name: {}", config.app_name);
    println!("Port: {}", config.port);
    println!("Debug mode: {}", config.debug);
    println!("Database URL: {}", config.database_url);
}
  1. 生成的config.rs文件内容大致如下:
use std::borrow::Cow;
use serde::{Serialize, Deserialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
#[allow(non_camel_case_types)]
pub struct Config {
    pub app_name: Cow<'static, str>,
    pub port: u16,
    pub debug: bool,
    pub database_url: Cow<'static, str>,
}

pub const CONFIG: Config = Config {
    app_name: Cow::Borrowed("My App"),
    port: 8080,
    debug: true,
    database_url: Cow::Borrowed("postgres://user:pass@localhost/db"),
};

impl Config {
    pub fn load() -> Self {
        #[cfg(debug_assertions)]
        {
            let config_str = std::fs::read_to_string("config.toml")
                .expect("Failed to read config file");
            toml::from_str(&config_str).expect("Failed to parse config file")
        }
        #[cfg(not(debug_assertions))]
        {
            CONFIG
        }
    }
}

1 回复

Rust配置管理库config_struct的使用指南

config_struct是一个Rust库,用于自动化生成类型安全的配置结构体,并支持从环境变量和配置文件解析配置。

主要特性

  • 自动生成类型安全的配置结构体
  • 支持从环境变量加载配置
  • 支持从JSON、TOML、YAML等配置文件加载
  • 提供默认值支持
  • 支持嵌套配置结构

安装

在Cargo.toml中添加依赖:

[dependencies]
config_struct = "0.5"
serde = { version = "1.0", features = ["derive"] }

基本使用方法

1. 定义配置模板

创建一个JSON文件作为配置模板,例如config_template.json

{
    "server": {
        "host": "localhost",
        "port": 8080
    },
    "database": {
        "url": "postgres://user:pass@localhost/db",
        "pool_size": 5
    },
    "debug_mode": false
}

2. 生成Rust配置结构体

使用config_struct的构建脚本来自动生成配置结构体。在build.rs中添加:

use config_struct::{Error, StructOptions};

fn main() -> Result<(), Error> {
    config_struct::create_config(
        "config_template.json",
        "src/config.rs",
        &StructOptions {
            serde_support: true,
            ..Default::default()
        })?;

    Ok(())
}

3. 使用生成的配置结构体

生成的src/config.rs文件将包含类型安全的配置结构体。在你的代码中可以这样使用:

mod config;
use config::Config;

fn main() {
    // 从环境变量加载配置
    let config = Config::from_env().expect("Failed to load config from env");
    
    println!("Server running on {}:{}", config.server.host, config.server.port);
    println!("Database URL: {}", config.database.url);
    
    if config.debug_mode {
        println!("Debug mode enabled");
    }
}

完整示例demo

以下是使用config_struct的完整示例:

  1. 项目结构
my_app/
├── Cargo.toml
├── build.rs
├── config_template.json
└── src/
    └── main.rs
  1. Cargo.toml
[package]
name = "my_app"
version = "0.1.0"
edition = "2021"

[dependencies]
config_struct = "0.5"
serde = { version = "1.0", features = ["derive"] }
  1. config_template.json
{
    "app": {
        "name": "MyApp",
        "version": "1.0.0"
    },
    "features": {
        "auth": true,
        "logging": false
    },
    "max_connections": 100
}
  1. build.rs
use config_struct::{Error, StructOptions};

fn main() -> Result<(), Error> {
    config_struct::create_config(
        "config_template.json",
        "src/config.rs",
        &StructOptions {
            serde_support: true,
            generate_loaders: true,
            ..Default::default()
        })?;

    Ok(())
}
  1. src/main.rs
mod config;
use config::Config;

fn main() {
    // 从环境变量加载配置
    let config = match Config::from_env() {
        Ok(c) => c,
        Err(e) => {
            eprintln!("Failed to load config from env: {}", e);
            // 从默认配置文件加载作为回退
            Config::from_json_file("config.json")
                .expect("Failed to load config from file")
        }
    };
    
    println!("Running {} v{}", config.app.name, config.app.version);
    
    if config.features.auth {
        println!("Authentication feature is enabled");
    }
    
    if config.features.logging {
        println!("Logging feature is enabled");
    }
    
    println!("Max connections: {}", config.max_connections);
    
    // 示例:使用环境变量覆盖配置
    println!("\nTry running with environment variables:");
    println!("export APP_NAME=\"MyApp2\"");
    println!("export FEATURES_AUTH=false");
    println!("export MAX_CONNECTIONS=200");
}

高级用法

从文件加载配置

use config::Config;

fn main() {
    // 从JSON文件加载
    let config = Config::from_json_file("config.json")
        .expect("Failed to load config from file");
    
    // 或者从TOML文件加载
    let config = Config::from_toml_file("config.toml")
        .expect("Failed to load config from file");
}

环境变量映射

默认情况下,config_struct会将字段名转换为大写加下划线的形式作为环境变量名:

  • server.hostSERVER_HOST
  • database.pool_sizeDATABASE_POOL_SIZE

你可以通过环境变量来覆盖配置:

export SERVER_PORT=9090
export DATABASE_URL="postgres://newuser:newpass@remotehost/db"

自定义选项

在生成结构体时可以自定义各种选项:

StructOptions {
    serde_support: true,      // 启用serde支持
    generate_loaders: true,   // 生成from_env, from_file等方法
    env_prefix: "MYAPP_",     // 自定义环境变量前缀
    ..Default::default()
}

注意事项

  1. 每次修改配置模板后需要重新运行构建(cargo build)以更新生成的Rust代码
  2. 环境变量值需要能够解析为对应的Rust类型
  3. 对于可选字段,可以在模板中使用null表示

config_struct通过自动化生成类型安全的配置结构体,大大简化了Rust应用程序的配置管理,同时保证了配置访问的类型安全性。

回到顶部