clienvtoml

用于从环境变量、命令行参数生成 toml,然后与已有的 toml 文件做配置合并。

先设置环境变量 source ./env:

rust export TEST_server__host=127.0.0.1 export TEST_site__title="xxAI.Art - 我们计算艺术" export TEST_grpc_port=9999 export TEST_site__xxai_art__mail=xxai.art@gmail.com export TEST_compress=true

用法见 ./src/lib.rs :

```rust use std::env::vars;

mod env; pub use env::{envwithprefix, kv_toml}; use serde::de::DeserializeOwned; mod merge; use std::path::Path;

pub use merge::merge;

[test]

fn test() { let config = "grpcport=1234 mysqlport=1235

[site] title=\"a b c\" password=\"xyz\"

[site.xxai_art] hide=true "; println!("\n## toml config\n\ntoml\n{config}\n");

let env = envwithprefix(vars(), "TEST_");

let envtoml = kvtoml(env, "__"); println!("## convert env into toml\n\ntoml\n{env_toml}\n");

let mut config = config.parse().unwrap(); merge(&mut config, &envtoml.parse().unwrap()); let config = toml::ser::tostring_pretty(&config).unwrap(); println!("## merge config and env\n\ntoml\n{config}\n"); }

/// 从 命令行、环境变量、配置文件 读取参数(前面的会覆盖后面的设置) pub fn clienvtomlvalue( cli: Option>>, envprefix: impl AsRef, tomlpath: Option>, ) -> anyhow::Result { let toml = if let Some(path) = tomlpath { std::fs::readtostring(path)? } else { String::new() };

let mut config = toml.parse()?;

// 从环境变量读取配置 { let envtoml = kvtoml(envwithprefix(vars(), envprefix), ""); merge(&mut config, &envtoml.parse().unwrap()); }

// 从命令行参数读取配置 if let Some(cli) = cli { let cli: Vec<(String, String)> = cli .iter() .filtermap(|s| { let s = s.asref(); if let Some(index) = s.find('=') { let (left, right) = s.splitat(index); Some((left.tostring(), right[1..].tostring())) } else { None } }) .collect(); let clitoml = kvtoml(cli, "."); merge(&mut config, &clitoml.parse().unwrap()); }; Ok(config) }

pub fn clienvtomlstr( cli: Option>>, envprefix: impl AsRef, tomlpath: Option>, ) -> anyhow::Result { let config = clienvtomlvalue(cli, envprefix, tomlpath)?; Ok(toml::ser::tostringpretty(&config)?) }

pub fn clienvtoml( cli: Option>>, envprefix: impl AsRef, tomlpath: Option>, ) -> anyhow::Result { let config = clienvtomlvalue(cli, envprefix, toml_path)?; Ok(T::deserialize(config)?) } ```

test 输出为 :

toml config

```toml grpcport=1234 mysqlport=1235

[site] title="a b c" password="xyz"

[site.xxai_art] hide=true

```

convert env into toml

```toml grpcport=9999 compress=true [site.xxaiart] mail="xxai.art@gmail.com" [server] host="127.0.0.1" [site] title="xxAI.Art - 我们计算艺术"

```

merge config and env

```toml compress = true grpcport = 9999 mysqlport = 1235

[server] host = "127.0.0.1"

[site] password = "xyz" title = "xxAI.Art - 我们计算艺术"

[site.xxai_art] hide = true mail = "xxai.art@gmail.com"

```