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 直接)
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_macro
的 derive
功能,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
自动实现容器。这允许容器展开通过容器传播。
可能失败的
特殊的容器类型 Fallible
和 Optional
为类型打开的方式提供了一些小的变化。
可选
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