#serde #proc-macro #optionals #maybe-types

empty_type

定义和转换类型及其对应的“可能类型”的工具

4 个版本

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

1124数据结构

每月 23 次下载
3 个 crate 中使用 (通过 webpack-stats)

MIT/Apache

24KB
457

空类型

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

use empty_type::{EmptyType, Empty};

#[derive(EmptyType)]
#[empty(deserialize, default)]
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();
}

进程宏

上述行为是繁琐且复杂的。启用 derive 功能的 proc_macro 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 提供了对类型展开方式的微小变化。

可选

可选是围绕最初为可选的源类型创建的包装器。可选大致表示 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反序列化错误。任何反序列化错误都会导致输出默认类型。

_

依赖项

~180KB