Expand description

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 Deserializers 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);

Traits

Helper trait to allow calling deserialize_over on the deserializer itself instead of on the object.

Deserialize on top of an existing struct instance.

Derive Macros

Derive macro for the DeserializeOver trait.