#env-var #structs #serialization #enums #case-sensitive #f32 #derive

envious

将环境变量(可能嵌套)反序列化为自定义的结构体

5个版本

0.2.2 2023年6月2日
0.2.1 2023年4月5日
0.2.0 2023年3月27日
0.1.1 2023年2月3日
0.0.0 2023年2月3日

#239编码

Download history 864/week @ 2024-03-14 1215/week @ 2024-03-21 1201/week @ 2024-03-28 1169/week @ 2024-04-04 1757/week @ 2024-04-11 2168/week @ 2024-04-18 2214/week @ 2024-04-25 1943/week @ 2024-05-02 1343/week @ 2024-05-09 1434/week @ 2024-05-16 1833/week @ 2024-05-23 1510/week @ 2024-05-30 938/week @ 2024-06-06 1830/week @ 2024-06-13 1358/week @ 2024-06-20 917/week @ 2024-06-27

5,170 每月下载次数
用于 confik

MIT/Apache

225KB
609

envious cover image

Bors enabled Crates.io Docs.rs

envious 允许您从环境变量中反序列化启用 serde 的结构体。

看看它的实际应用

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug)]
enum StaircaseOrientation {
    Left,
    Right,
}

#[derive(Serialize, Deserialize, Debug)]
struct Config {
    target_temp: f32,
    automate_doors: bool,

    staircase_orientation: StaircaseOrientation,
}

let config: Config = envious::Config::default().build_from_env().expect("Could not deserialize from env");

使用以下环境变量

export target_temp=25.0
export automate_doors=true
export staircase_orientation=Left

它将从环境变量中解析它,并为您提供可以在应用程序中使用的数据结构。

注意: 默认情况下,环境变量是大小写敏感的!这可以通过使用 Config::case_sensitive 方法进行修改。

envious 还支持通过 Config::with_prefix 方法仅接受前缀环境变量。这将在此进一步处理之前将其删除。

入门

要使用 envious,只需将其添加到您的 Cargo.toml,如下所示

cargo add envious

然后使用 Config::defaultConfig::build_from_env 从环境变量中反序列化!

⚠️ 当前不足之处

  • 目前元组枚举变体不能超过一个元素!
  • 数组顺序对环境顺序高度敏感
    • 目前没有进行排序,顺序取决于操作系统如何传递变量
  • 当在其他格式中需要 null 时,目前无法进行反序列化
    • 有关更多详细信息,请参阅 #12

反序列化是如何工作的

环境变量和 serde 模型之间的映射如下

嵌套字段由提供的分隔符分隔。

这可以通过使用 Config::with_separator 进行修改,默认为 __(双下划线)。例如,如果您有以下结构体

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
struct Radiator {
    min_temp: f32,
    max_temp: f32,
}

#[derive(Serialize, Deserialize)]
struct Config {
    target_temp: f32,
    radiator: Option<Radiator>
}

您可以使用以下变量反序列化 Config

export target_temp=21.0
export radiator__min_temp=15.0
export radiator__max_temp=30.0

数组使用嵌套字段进行序列化,各个键将被丢弃。

数组表示为匿名结构体,其中的“字段”是各个元素。

一个更复杂的例子可能如下所示

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
enum Material {
    Wood,
    Plastic,
}

#[derive(Serialize, Deserialize)]
struct Door {
    width: f32,
    height: f32,
    material: Material,
}

#[derive(Serialize, Deserialize)]
struct House {
    age: u32,
    entrance_doors: Vec<Door>,
}

现在,为了反序列化一个 House,我们可以设置以下变量

export age=120
export entrance_doors__0__width=100
export entrance_doors__0__height=100
export entrance_doors__0__material="Wood"
export entrance_doors__1__width=200
export entrance_doors__1__height=120
export entrance_doors__1__material="Plastic"
export entrance_doors__foo__width=400
export entrance_doors__foo__height=20
export entrance_doors__foo__material="Plastic"

如你所见,数组中各个“键”并不重要!不过,相同的键指的是相同的对象。

单元枚举变体(没有字段)从字符串进行序列化

如上面的示例所示,Material 枚举直接从变体名称进行反序列化。 请注意大小写,如果你已经通过 Config::case_sensitive 启用了大小写敏感,大小写必须是 完全相同 的!

复杂的枚举变体序列化方式与结构体相同

默认情况下,serde 使用外部标记来处理更复杂的枚举变体。元组枚举目前仅支持单个值。

为了理解这意味什么,让我们以这个枚举为例

use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]
enum Shape {
    Rectangle { width: f32, height: f32 },
    Circle(f32),
    Nothing,
}

#[derive(Serialize, Deserialize)]
struct Config {
    expected_shape: Shape,
}

为了在这里反序列化 Config,我们可以使用以下变量

export expected_shape__Rectangle__width=50.0
export expected_shape__Rectangle__height=10.0

// OR

export expected_shape__Circle=15.0

// OR

export expected_shape=Nothing

这些变量组中的任何一个都会给出预期的结果。

如果你更改了结构体的标记,请确保调整所提供的变量。

许可证

envious 根据 MIT 许可证或 Apache 2.0 许可证进行许可,由你选择。

贡献

要为 envious 贡献,你可以

  • 提出包含想法、意见、错误报告等问题...
  • 进行分支,实现新功能,并将它们作为拉取请求发送
  • 给它一个 Star 并传播信息! ;)

依赖关系

~0.4–1MB
~23K SLoC