3个版本
0.1.2 | 2023年6月22日 |
---|---|
0.1.1 | 2022年10月1日 |
0.1.0 | 2021年7月7日 |
148 在 #options
1,434 每月下载量
在 3 个crate中使用(通过 optional-field)
8KB
134 行
可选字段
想用Rust谋生?CV Partner正在招聘伦敦、奥斯陆、哥本哈根和斯德哥尔摩的Rust开发者。 查看职业页面
为可以表示为三种状态(缺失、存在但为null和存在且具有值)的值提供Rust类型和序列化/反序列化实现。
pub enum Field<T> {
Missing,
Present(Option<T>),
}
当使用JSON或其他格式,且serde默认将缺失键和null值视为相同,将它们反序列化为Option::None
时,这可能很有用。在序列化时也存在类似问题,你必须创建自己的三态枚举,并使用skip_serializing_if
在字段上标记,以避免序列化该字段。
当API提供部分对象或差异,而你不知道是否需要将值设置为null或是否应保留值不变时,这可能会导致问题。
通过使用Field
,您可以区分null值和缺失键,并让serde在这些场景下正确行为。
use serde::{Deserialize, Serialize};
use serde_json::json;
use optional_field::{Field, serde_optional_fields};
#[serde_optional_fields]
#[derive(Debug, Serialize, Deserialize)]
struct Thing {
one: Field<u8>,
two: Field<u8>,
three: Field<u8>,
}
fn main() {
let thing = serde_json::from_value::<Thing>(json!(
{
"one": 1,
"two": null,
}
))
.unwrap();
assert_eq!(Field::Present(Some(1)), thing.one);
assert_eq!(Field::Present(None), thing.two);
assert_eq!(Field::Missing, thing.three);
}
用法
字段实现了您熟悉的许多Option方法,例如map
、unwrap
、as_ref
等。Field
将为这些方法返回Option
内的值,同时也提供了一套访问Option
本身的方法。这些等效方法遵循在方法名后添加_present
的模式。例如,给定Present(Some(100))
,unwrap()
将返回100
,而unwrap_present()
将返回Some(100)
。
use optional_field::Field;
struct Thing {
one: Field<u8>,
two: Field<u8>,
three: Field<u8>,
}
fn main() {
let num_field = Field::Present(Some(100));
// Calling map gets the value out of the Option within Present
assert_eq!(200, num_field.map(|n| n * 2));
// Calling map_present gets the option out of Present
assert_eq!(false, num_field.map_present(|opt| opt.is_none()));
}
功能
默认情况下,optional-field
依赖于serde和serde宏。如果您想在不引入serde的情况下使用optional-field
,可以将default-features
设置为false。
[dependencies]
optional-field = { version = "0.1.5", default-features = false }
许可证
MIT许可证(《LICENSE.txt》或http://opensource.org/licenses/MIT》)
依赖项
~1.5MB
~34K SLoC