#可选 #序列化 #serde #对应物

empty_type_traits

类型及其可选对应物之间的转换

4 个版本

0.2.2 2022 年 7 月 5 日
0.2.1 2022 年 6 月 22 日
0.2.0 2022 年 6 月 22 日
0.1.0 2022 年 6 月 21 日

#1066编码

每月 41 次下载
5 个 crate 中使用 (2 直接)

Apache-2.0

18KB
435

空类型

EmptyType 特性和 Container 特性协同工作,创建具有可选成员的结构,并提供两者之间的转换 API。

use empty_type::{EmptyType, Empty};

#[derive(EmptyType)]
#[empty(deserialize, fail_safe)]
struct Data {
    key: String,
    mismatch: usize
}

const JSON: &str = r#"{ "key": "value", "mismatch": "not a number" }"#; 


fn main() {
    let empty: Empty<Data> = serde_json::from_str(JSON).unwrap();
    assert!(empty.key.is_some());
    assert!(empty.mismatch.is_none());
    
    let resolved = empty.resolve();
    assert_eq!(resolved.key.as_str(), "value");
    // when the "default" flag is set, even serde errors get resolved
    assert_eq!(resolved.mismatch, 0);
}

过程宏创建的代码大致相当于以下内容

use empty_type::{EmptyType, Container};

struct Data {
    key: String
}

#[derive(Default)]
struct OptionalData {
   key: Option<String>
}

impl EmptyType for Data {
    type Container = OptionalData;
}

impl Container for OptionalData {
#    type Value = Data;
#    
#    fn try_open(&mut self) -> Result<Self::Value, Box<dyn std::error::Error>> {
#        Ok(Data {
#            key: self.key.open()
#        })
#    }
}

// This allows conversion between the two types 

fn main() {
    let mut empty = Data::new_empty();
    empty.key = Some(String::new());
    // should be the default value
    let resolved = empty.resolve();
}

过程宏

上述行为繁琐且复杂。启用 proc_macroderive 功能,EmptyType 过程宏为您创建可选数据结构。

Serde

通过 serde 功能标志提供 Serde 支持,并提供了一个辅助函数 deserialize_empty 用于反序列化空值。

# use empty_type::{EmptyType, deserialize_empty};
# use serde::Deserialize;

#[derive(EmptyType)]
#[empty(deserialize)]
struct Data {
    value: String
}

const JSON: &str = r#" { "value": "data" } "#;

fn use_with_deserializer() {
    let mut de = serde_json::Deserializer::from_str(JSON);
    let empty_value = deserialize_empty::<Data, _>(&mut de).unwrap();
    
    let full_value = empty_value.resolve();
    
    assert_eq!(full_value.value.as_str(), "data");
}

fn use_implicit_deserialization() {
    let value: empty_type::Empty<Data> = serde_json::from_str(JSON).unwrap();
    let full_value = value.resolve();

    assert_eq!(full_value.value.as_str(), "data");
}

# fn main() {
#   use_with_deserializer();
# }

容器

Option<T>bool 自动实现容器。这允许容器展开通过容器传播。

可能失败的

特殊的容器类型 FallibleOptional 为类型打开的方式提供了一些小的变化。

可选

Optional 是一种围绕初始为可选类型的包装器。Optional 大约表示 Some(Option<T>)。打开这个容器始终会得到一个 Option。这与 Option<Option<T>> 不同,因为它不可能在描述的语义下被包装的选项为 None

use empty_type::Optional;
struct Data {
    optional_data: Option<String>
}

struct MaybeData {
    optional_data: Optional<Option<String>>
}

可能失败的

Fallible 类似于 Optional,但它要求底层类型实现 Default。fallible 的语义是始终返回底层 Container 的默认值。

另一个重要的区别是,Fallible 将吞咽 serde Deserialize 错误。任何反序列化错误都将导致发出默认类型。

_

依赖项

~170KB