rust-embedded-community/serde-json-core

Trying to deserialize the wrong json result in a panic

gbip opened this issue · 5 comments

gbip commented

When trying to deserialize a valid json that does not represent the expected struct, the deserializer calls deserialize_ignored_any which should be unreachable.

Here is an example inspired by some code that we used in production :

use serde_json_core::de::{from_slice, Error as DError};

#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
pub enum IOState {
    On,
    Off,
}

#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
pub struct Pneumatic {
    pub pumps: [IOState; 2],
    pub pump_intensity: [u16; 2],
    pub valves: [IOState; 6],
}

impl Pneumatic {
    fn from_json_slice(slice: &[u8]) -> Result<Self, DError> {
        from_slice(slice)
    }
}
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn deser_fail() {
        let b = Pneumatic::from_json_slice(
            "{\"pump_intensity\":[0,0],\"pumps\":[\"On\",\"On\"],\"valves\":[\"Off\",\"On\",\"On\",\"Off\",\"On\",\"Off\"]}".as_bytes()).unwrap();
       // This line fails
        let c = Pneumatic::from_json_slice(
            "{\"tirette\":\"Triggered\",\"buzzer\":\"PlayErrorSound\"}".as_bytes(),
        );
    }

}

You can find the code to replicate this issue on this branch (ready to be cloned).

Please tell me if I can do anything else to document this issue ! 😄

This threw me as well.

Would it make sense for deserialize_ignored_any to return an Error rather than crash?

I actually was able to implement deserialize_ignored_any in #13, which could solve this.

The derive Deserializer implementation uses deserialize_ignored_any to toss fields that it doesn’t recognize.

Is this done with #13 being merged?

Think this issue can be closed with #13 merged?

Closed by #13