#serde-json #struct #instance #deserialize-json #data #onto #serde-default

serde-deserialize-over

通过serde将结构体反序列化到现有实例上

2个版本

0.1.1 2022年6月7日
0.1.0 2022年2月27日

#1969 in 编码

MIT/Apache

17KB
326

Traits和macros用于通过serde将数据反序列化到现有结构体实例上。它类似于一个功能更强大的版本,除了它能够使用运行时数据而不是硬编码的默认值。

使用方法

此crate的主要trait是DeserializeOver trait及其对应的derive macro。它的工作原理与serde的Deserialize trait类似,除了不在数据中不存在的结构体字段保留其值。

对于简单的结构体,这最终看起来像这样

use serde_deserialize_over::DeserializeOver;

#[derive(DeserializeOver)]
struct MyStruct {
    pub a: String,
    pub b: i32
}

let json = r#"{ "a": "test" }"#;
let mut inst = MyStruct {
    a: "a string".to_owned(),
    b: 32
};

let mut de = Deserializer::new(StrRead::new(json));
inst.deserialize_over(&mut de)
    .expect("Failed to deserialize JSON");

assert_eq!(inst.a, "test");
assert_eq!(inst.b, 32);

这里,序列化的json只为a字段有一个值,因此当它被反序列化到现有实例上时,a字段被更新,而b字段保持不变。

嵌套结构体

默认情况下,结构体的字段使用serde的Deserialize进行反序列化。这意味着默认情况下,嵌套结构体必须完整反序列化,不能在现有数据之上反序列化。为了标记子字段应该通过DeserializeOver derive macro进行反序列化,该宏支持#[deserialize_over]属性。

use serde_deserialize_over::DeserializeOver;

#[derive(DeserializeOver, Default)]
struct Inner {
    a: i32,
    b: i32
}

#[derive(DeserializeOver, Default)]
struct Outer {
    #[deserialize_over]
    inner: Inner,
    c: i32
}

let json = r#"{ "inner": { "b": 5 } }"#;
let mut inst = Outer::default();

let mut de = Deserializer::new(StrRead::new(json));
inst.deserialize_over(&mut de)
    .expect("Failed to deserialize JSON");

assert_eq!(inst.inner.a, 0);
assert_eq!(inst.inner.b, 5);
assert_eq!(inst.c, 0);

附加功能

此crate还提供了对所有serde DeserializerDeserializeInto扩展trait,它接受操作数的顺序相反。

use serde_deserialize_over::{DeserializeOver, DeserializeInto};

#[derive(DeserializeOver, Default)]
struct MyStruct {
    pub a: String,
    pub b: i32
}

let json = r#"{ "a": "test" }"#;
let mut inst = MyStruct::default();

let mut de = Deserializer::new(StrRead::new(json));
de.deserialize_into(&mut inst)
  .expect("Failed to deserialize JSON");

assert_eq!(inst.a, "test");
assert_eq!(inst.b, 0);

依赖关系

~4MB
~79K SLoC