msgpack-rust icon indicating copy to clipboard operation
msgpack-rust copied to clipboard

Error when deserializing untagged variant of enum

Open Scripter17 opened this issue 1 year ago • 1 comments

#148 and #149 address when an entire enum is #[serde(untagged)], but if just a single variant is untagged an error occurs.

The following code works fine for deserializing B but panics when deserializing A.

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
enum A {
    #[serde(untagged)]
    A {
        a: u8
    }
}

#[derive(Serialize, Deserialize)]
#[serde(untagged)]
enum B {
    C(C)
}

#[derive(Serialize, Deserialize)]
enum C {
    C
}

fn main() {
    let data = rmp_serde::to_vec(&B::C(C::C)).unwrap();
    rmp_serde::from_slice::<B>(&data).unwrap();
    let data = rmp_serde::to_vec(&A::A{a: 2}).unwrap();
    rmp_serde::from_slice::<A>(&data).unwrap();
}

Scripter17 avatar Sep 18 '24 09:09 Scripter17

Here is another example:


#[cfg(test)]
mod tests {
    use serde::{Deserialize, Serialize};
    use std::net::SocketAddr;

    #[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq, Hash)]
    #[serde(untagged)]
    pub enum MaybeResolvedAddr {
        Resolved(SocketAddr),
        Unresolved(String),
    }

    #[test]
    fn test_maybe_resolved_addr() -> anyhow::Result<()> {
        let addr = MaybeResolvedAddr::Resolved("127.0.0.1:1234".parse()?);
        rmp_serde::from_slice::<MaybeResolvedAddr>(&rmp_serde::to_vec(&addr)?)?;
        Ok(())
    }

    #[test]
    fn test_maybe_resolved_addr_json() -> anyhow::Result<()> {
        let addr = MaybeResolvedAddr::Resolved("127.0.0.1:1234".parse()?);
        serde_json::from_str::<MaybeResolvedAddr>(&serde_json::to_string(&addr)?)?;
        Ok(())
    }
}

It will produce such an error:

Error: data did not match any variant of untagged enum MaybeResolvedAddr

And serde_json works.

zerolfx avatar Jan 15 '25 10:01 zerolfx