2 releases
0.1.1 | Jun 7, 2022 |
---|---|
0.1.0 | Feb 27, 2022 |
#1969 in Encoding
17KB
326 lines
Traits and macros for deserializing data onto an existing instance of a
struct via serde. It is somewhat like a more featureful version of adding
#[serde::default(...)]
annotations everywhere except that it is able to
use runtime data instead of hardcoded defaults.
Usage
The main trait for this crate is the DeserializeOver
trait and its
corresponding derive macro. It works analogously to serde's Deserialize
trait except that struct fields that are not present within the data being
deserialized keep their values as is.
For a simple struct, this ends up looking something like this:
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);
Here, the serialized json only has a value for the a
field so when it gets
deserialized over the existing instance the a
field is updated while the
b
field remains unchanged.
Nested Structs
By default, the fields of the struct are deserialized using serde's
Deserialize
. This means that, by default, nested structs must be
deserialized in entirety and cannot be deserialized on top of existing data.
To mark that subfields should instead be deserialized via
DeserializeOver
the derive macro supports the #[deserialize_over]
attribute.
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);
Extras
This crate also provides the DeserializeInto
extension trait on all
serde Deserializer
s which takes the operands in the other order.
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);
Dependencies
~4MB
~79K SLoC