#configuration #environment #config-file

configer

使用 Rust 实现的简单配置管理

11 个版本 (5 个重大更改)

0.6.0 2024 年 3 月 18 日
0.5.1 2024 年 3 月 18 日
0.4.3 2024 年 3 月 17 日
0.3.0 2024 年 3 月 15 日
0.1.0 2024 年 3 月 11 日

#73 in 配置

Download history 67/week @ 2024-04-01

每月 396 次下载

Apache-2.0

91KB
1.5K SLoC

configer

使用 Rust 实现的简单配置管理。

API 文档

变更日志

1.使用

将此添加到您的 Cargo.toml

[dependencies]
configer = "0.6"

# Or
# If necessary
configer = { version = "0.6", features = ["usetoml"] }

2.APIs

注意:目前尚不稳定,就像玩具一样。在生产环境中使用时请谨慎。

2.1.new

let mut configer = ConfigerEnvironment::new();

2.2.set

  • 支持嵌套键设置

2.2.1.Err

let mut configer = ConfigerEnvironment::new();

let empty_rvt = configer.set("", "Rust".into());
assert_eq!(empty_rvt, Err(ConfigerError::EmptyKey));

2.2.2.Ok

let mut configer = ConfigerEnvironment::new();

configer.set("io.github.photowey.string", String::from("Hello, Configer!").into()).unwrap();
configer.set("io.github.photowey.str", "Rust".into()).unwrap();

let rvt = snowflake_dynamic!().unwrap() as i64;
configer.set("io.github.photowey.i32", 123_i32.into()).unwrap();
configer.set("io.github.photowey.i64", rvt.into()).unwrap();

let pi = PI as f64;
configer.set("io.github.photowey.configer.f32", 9527.8848_f32.into()).unwrap();
configer.set("io.github.photowey.configer.f64", pi.into()).unwrap();

let now = NaiveDateTime::parse_from_str("2024-03-11 22:50:00", DateTimePattern::YYYY_MM_DD_HH_MM_SS).unwrap();
configer.set("io.github.photowey.configer.Time", now.into()).unwrap();

2.2.3.set_t

  • 更新签名 @since 0.4.3
let mut configer = ConfigerEnvironment::new();
// set
// configer.set("io.github.photowey.string", String::from("Hello, Configer!").into()).unwrap();
// set_t
configer.set_t("io.github.photowey.string", String::from("Hello, Configer!")).unwrap();

// set
// configer.set("io.github.photowey.str", "Rust".into()).unwrap();
// set_t
configer.set_t("io.github.photowey.str", "Rust").unwrap();

let rvt = snowflake_dynamic!().unwrap() as i64;
configer.set_t("io.github.photowey.i32", 123_i32).unwrap();
configer.set_t("io.github.photowey.i64", rvt).unwrap();

let pi = PI as f64;
configer.set_t("io.github.photowey.configer.f32", 9527.8848_f32).unwrap();
configer.set_t("io.github.photowey.configer.f64", pi).unwrap();

let now = NaiveDateTime::parse_from_str("2024-03-11 22:50:00", DateTimePattern::YYYY_MM_DD_HH_MM_SS).unwrap();
configer.set_t("io.github.photowey.configer.Time", now).unwrap();

2.3.get

2.3.1.Err

let mut configer = ConfigerEnvironment::new();
configer.set("io.github.photowey.configer.ok", "Rust".into()).unwrap();

assert_eq!(configer.get("io.github.photowey.configer.not.found"), Err(ConfigerError::NotFound));

2.3.2.Ok

let mut configer = ConfigerEnvironment::new();

configer.set("io.github.photowey.string", String::from("Hello, Configer!").into()).unwrap();
configer.set("io.github.photowey.str", "Rust".into()).unwrap();

let rvt = snowflake_dynamic!().unwrap() as i64;
configer.set("io.github.photowey.i32", 123_i32.into()).unwrap();
configer.set("io.github.photowey.i64", rvt.into()).unwrap();

let pi = PI as f64;
configer.set("io.github.photowey.configer.f32", 9527.8848_f32.into()).unwrap();
configer.set("io.github.photowey.configer.f64", pi.into()).unwrap();

let now = NaiveDateTime::parse_from_str("2024-03-11 22:50:00", DateTimePattern::YYYY_MM_DD_HH_MM_SS).unwrap();
configer.set("io.github.photowey.configer.Time", now.into()).unwrap();

assert_eq!(configer.get("io.github.photowey.string"), Ok(&Node::String(String::from("Hello, Configer!").into())));
assert_eq!(configer.get("io.github.photowey.str"), Ok(&Node::String(String::from("Rust").into())));
assert_eq!(configer.get("io.github.photowey.i32"), Ok(&Node::Int32(123_i32)));
assert_eq!(configer.get("io.github.photowey.i64"), Ok(&Node::Int64(rvt)));
assert_eq!(configer.get("io.github.photowey.configer.f32"), Ok(&Node::Float32(9527.8848_f32)));
assert_eq!(configer.get("io.github.photowey.configer.f64"), Ok(&Node::Float64(pi)));
assert_eq!(configer.get("io.github.photowey.configer.Time"), Ok(&Node::DateTime(now)));

2.3.3.Convert

  • 转换 &Node
2.3.3.1.Nested
let mut configer = ConfigerEnvironment::new();

let mut nested = Table::new();
nested.insert("Hello".to_string(), Node::String("Rust".to_string()));

configer
.set("io.github.photowey.nested", Node::Nested(nested))
.unwrap();

let rvt_nested = configer.get("io.github.photowey.nested");

if let Some(into_value) = NodeConverter::try_nested(rvt_nested) {
	match into_value.get("Hello") {
        Some(node) => {
            assert_eq ! ( * node, Node::String("Rust".to_string()));
        },
        _ => {}
    }
} else {
    panic ! ("failed to convert the value to Table")
}
2.3.3.2.Array
let mut configer = ConfigerEnvironment::new();
let now = 1710265983u32;
let mut array = domain::Array::new();
array.push(Node::String("Rust".to_string()));
array.push(Node::IntU32(now));

configer
.set("io.github.photowey.array", Node::Array(array))
.unwrap();

let rvt_array = configer.get("io.github.photowey.array");

let mut image = domain::Array::new();
image.push(Node::String("Rust".to_string()));
image.push(Node::IntU32(now));

if let Some(into_value) = NodeConverter::try_array(rvt_array) {
    assert!(assert_array_equals(into_value, &image));
} else {
    panic!("failed to convert the value to Table")
}
2.3.3.3.DateTime
let mut configer = ConfigerEnvironment::new();

let now = NaiveDateTime::parse_from_str("2024-03-11 22:50:00", DateTimePattern::YYYY_MM_DD_HH_MM_SS).unwrap();
configer.set("io.github.photowey.configer.Time", now.into()).unwrap();

let rvt_time = configer.get("io.github.photowey.configer.Time");

// match
match rvt_time {
    Ok(node) => {
        match node {
            Node::DateTime(ref time) => {
                assert_eq!(*time, now);
            }
            _ => {}
        }
    }
    _ => {}
}

// converter
if let Some(into_value) = NodeConverter::try_datetime(rvt_time) {
    assert_eq!(*into_value, now);
} else {
    panic!("failed to convert the value to NaiveDateTime")
}
2.3.4.4....

3.Reader

  • @since0.3.0

3.1.toml

3.1.1.new

let toml_reader = TomlConfigReader::default();

3.1.2.Read

3.1.2.1.path
let path = "resources/testdata/configer-dev.toml";
let toml_reader = TomlConfigReader::default();
let toml_rvt = toml_reader.read_from_path(path);
3.1.2.2.file content
let toml_reader = TomlConfigReader::default();

let path = "resources/testdata/configer-dev.toml";
let content = fs::read_to_string(path).expect("Failed to read config file");
let toml_from_content_rvt = toml_reader.read_from_str(&content);

4.ConfigerEnvironmentBuilder

  • @since0.4.0

4.1.With table

let path = "resources/testdata/configer-dev.toml";

let toml_reader = TomlConfigReader::default();
let toml_rvt = toml_reader.read_from_path(path);

if let Ok(table) = toml_rvt {
    // With table
    let builder_rvt = ConfigerEnvironment::builder()
    .with_table(table)
    .build();

    if let Ok(configer) = builder_rvt {
        let rvt_database_servers = configer.get("database.servers");

        return assert_configer_array(rvt_database_servers, "database.servers");
    }

    panic!("Failed to build ConfigerEnvironment")
}

panic!("Failed to read configer-dev.toml file")

4.2.With registry and path

  • 目前仅支持 toml 文件。
let path = "resources/testdata/configer-dev.toml";

let toml_reader = TomlConfigReader::default();
let mut registry = ConfigReaderRegistry::default();
registry.register(Box::new(toml_reader));

let builder_rvt = ConfigerEnvironment::builder()
.with_registry(Box::new(registry))
.with_path(path.to_string())
.build();

if let Ok(configer) = builder_rvt {
    let rvt_database_servers = configer.get("database.servers");
    return assert_configer_array(rvt_database_servers, "database.servers");
}

panic!("Failed to read configer-dev.toml file")

4.3.With table,registry and path

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let path = "resources/testdata/configer-dev.toml";

let toml_reader = TomlConfigReader::default();
let mut registry = ConfigReaderRegistry::default();
registry.register(Box::new(toml_reader));

let table = crate::env::try_load_env_variables();

let builder_rvt = ConfigerEnvironment::builder()
.with_table(table)
.with_registry(Box::new(registry))
.with_path(path.to_string())
.build();

if let Ok(configer) = builder_rvt {
    let rvt_database_servers = configer.get("database.servers");
    assert_configer_array(rvt_database_servers, "database.servers");

    let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
    assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

    return ();
}

panic!("Failed to read configer-dev.toml file")

4.4.With table,registry,path and profiles

  • @since0.6.0
env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let path = "resources/testdata/config.toml";

let toml_reader = TomlConfigReader::default();
let mut registry = ConfigReaderRegistry::default();
registry.register(Box::new(toml_reader));

let builder_rvt = ConfigerEnvironment::builder()
.with_registry(Box::new(registry))
.with_path(path.to_string())
// with profiles
.with_profiles(vec![String::from("dev"), String::from("shared")])
.build();

if let Ok(configer) = builder_rvt {
    // config-dev.toml
    let rvt_database_servers = configer.get("database.servers");
    assert_configer_array(rvt_database_servers, "database.servers");

    let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
    assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

    // config-shared.toml
    let config_shared_rvt = configer.get("strings");
    assert_configer_array_strings(config_shared_rvt, "strings");

    // config.toml
    let config_bool_rvt = configer.get("boolean_value");
    assert_eq!(config_bool_rvt, Ok(&Node::Boolean(true)));

    return ();
}

panic!("Failed to read configer-[dev, shared].toml file")

5.Load Environment variables

5.1.default

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let configer = ConfigerEnvironment::default();
let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

5.2.new

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let configer = ConfigerEnvironment::new();
let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

5.3.mixed_with_env_variables

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let configer = ConfigerEnvironment::mixed_with_env_variables(None, None);
let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

5.4.table

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let path = "resources/testdata/configer-dev.toml";

let toml_reader = TomlConfigReader::default();
let toml_rvt = toml_reader.read_from_path(path);

if let Ok(table) = toml_rvt {
    let configer = ConfigerEnvironment::table(table);

    let rvt_database_servers = configer.get("database.servers");
    assert_configer_array(rvt_database_servers, "database.servers");

    let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
    assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

    return ();
}

panic!("Failed to read configer-dev.toml file")

5.5.builder

env::set_var("CONFIGER_TEST_VAR", "rust.configer");

let path = "resources/testdata/configer-dev.toml";

let toml_reader = TomlConfigReader::default();
let mut registry = ConfigReaderRegistry::default();
registry.register(Box::new(toml_reader));

let builder_rvt = ConfigerEnvironment::builder()
.with_registry(Box::new(registry))
.with_path(path.to_string())
.build(); // load environment variables auto.

if let Ok(configer) = builder_rvt {
    let rvt_database_servers = configer.get("database.servers");
    assert_configer_array(rvt_database_servers, "database.servers");

    let env_var_rvt = configer.get("CONFIGER_TEST_VAR");
    assert_eq!(env_var_rvt, Ok(&Node::String(String::from("rust.configer"))));

    return ();
}

panic!("Failed to read configer-dev.toml file")

6.Next

  • 支持加载 config 文件 (P 0)。
    • configer.toml
      • @since0.3.0
    • configer-${profile}.toml
      • @since0.6.0
      • ConfigerEnvironmentBuilder
        • with_profiles
    • yaml | yml ?
    • 属性 ?
    • 初始化?
    • .环境?
    • JSON?
  • 自动加载环境变量(P 1)
  • 支持合并现有 HashMap<String,Node>/Table
  • 支持绑定 struct

7.文档

请稍等。

8.测试

8.1.cargo test

$ cargo test --features "usetoml" -- --show-output
$ cargo test --features "usetoml"

9.文档

9.1.功能

  • usetoml
$ cargo doc --open --features usetoml

依赖项

~1–1.4MB
~23K SLoC