Search code examples
jsonrustserde

How do I use `serde_stacker` in my `deserialize` implementation?


I have a struct that I can only deserialize if I use the serde_stacker. So in order to deserialize the struct Bar I need to first convert it to a serde_json::value::Value type that is used to hold JSON values, and then convert it to the desired Bar type.

const SIZE: usize = 30000;

#[derive(Clone, Debug, Serialize, Deserialize)]
struct Foo {
    #[serde(with = "BigArray")]
    vals: [bool; SIZE],
}

#[derive(Clone, Debug, Serialize, Deserialize)]
struct Bar {
    field0: Foo,
}

impl Bar {
    fn custom_deserialization_test(instance: Bar) {
        let json = serde_json::to_string(&instance).unwrap();
        let mut deserializer: serde_json::Deserializer<serde_json::de::StrRead> =
            serde_json::Deserializer::from_str(&json);
        let deserializer: serde_stacker::Deserializer<
            &mut serde_json::Deserializer<serde_json::de::StrRead>,
        > = serde_stacker::Deserializer::new(&mut deserializer);
        let value: Value = Value::deserialize(deserializer).unwrap();
        let target: Bar = from_value(value).unwrap();
    }
}

My question is: How do I overwrite Bar's deserialize method to use the serde_stacker deserializer instead of the regular serde_json deserializer as I do above?

I might need some kind of wrapper but the from_value function call on the last line of code uses the derived deserialize method of Bar to convert from the JSON object to type Bar.


Solution

  • The Bar::deserialize function is generic over the Deserializer used. This means you can use serde_stacker::Deserializer instead of a Deserializer from serde_json. Your posted code snippet already shows how to use serde_stacker on the Value type. You only need to replace it with Bar.

    impl Bar {
        fn custom_deserialization_test(instance: Bar) {
            let json = serde_json::to_string(&instance).unwrap();
            let mut deserializer: serde_json::Deserializer<serde_json::de::StrRead> =
                serde_json::Deserializer::from_str(&json);
            let deserializer: serde_stacker::Deserializer<
                &mut serde_json::Deserializer<serde_json::de::StrRead>,
            > = serde_stacker::Deserializer::new(&mut deserializer);
            let target = Bar::deserialize(deserializer).unwrap();
        }
    }