#default-value #deserialize #traits #struct #was #set #generated

default_aware

一个用于指示值是否是通过 Default 特性生成的微小的结构体

2 个不稳定版本

0.2.0 2023 年 8 月 21 日
0.1.0 2023 年 8 月 15 日

#1748解析器实现

MIT 许可证

9KB
137

Default-Aware

一个微小的结构体,用于指示值是否是通过 Default 特性生成的。

安装

[dependencies]
default_aware = "0.1.0"

使用方法

如果你正在反序列化一个结构体,并希望基于值是否被显式设置的行为,你可以使用 DefaultAware 结构体来包装相关的类型,然后在反序列化后检查它是否是由 Default 特性生成的,或者它是否来自反序列化的来源

use default_aware::DefaultAware;
use serde::{self, Deserialize};
use serde_json;

// This represents some value you might deserialize, which
// implements the `Default` trait.
#[derive(Deserialize, PartialEq, Debug)]
struct Port(u32);

impl Default for Port {
    fn default() -> Self {
        Port(8000)
    }
}

#[derive(Deserialize)]
pub struct MyConfig {
    #[serde(default)]
    http_port: DefaultAware<Port>,
}

fn main() {

    // The first config sets the port number to the same as the
    // default. If we weren't using the `DefaultAware` wrapper, the
    // value recieved after deserializing would be
    // indistinguishable from the default value. Therefore we could
    // not know if the `http_port` field was actually provided in
    // the document or not.
    let config1_json: &str = r#"{ "http_port": 8000 }"#;

    // But since we are using the `DefaultAware` wrapper, we can
    // easily tell that the value was not created via the `Default`
    // implementation.
    let config1: MyConfig = serde_json::from_str(config1_json)
        .unwrap();
    assert_eq!(false, config1.http_port.is_default());
    assert_eq!(Port(8000), config1.http_port.unwrap());


    // We can demonstrate the behavior when the default value is
    // used by checking the output
    // on a document that omits the `http_port` field.
    const config2_json: &str = r#"{  }"#;

    // The field has the same wrapped value as before, but notice
    // that we tell it was created via the Default implementation.

    let config2: MyConfig = serde_json::from_str(config2_json)
        .unwrap();
    assert_eq!(Port(8000), *config2.http_port.as_ref());
    assert_eq!(true, config2.http_port.is_default());

    // The type is just an enun, so we can use all the typical enum
    // patterns
    match config2.http_port {
        DefaultAware::Default(_) =>
            println!("value set by default"),
        DefaultAware::Declared(_) =>
            println!("value set in the config"),
    }

    if let DefaultAware::Default(_) = config2.http_port {
        println!("Port number not set! Running on port 8000 by \
            default. Silence this warning by setting the \
            `http_port` field in your config.");
    }
}

功能

Serde 功能由功能 serde 保护,并默认启用。你可以通过以下方式列出依赖项来在不使用 serde 的情况下使用此软件包

[dependencies]
default_aware = { version = "0.1.0", default-features = false }

依赖项

~0.4–1MB
~23K SLoC