pyfisch/cbor

Untagged enum with one named field doesn't round-trip

Erutuon opened this issue · 0 comments

So I have a variant of an enum, Contributor::Ip, and an equivalent struct IpContributor. The struct round-trips through serialization and deserialization but the enum variant with just one field doesn't, so this test gives a panic on the last assert_round_trip. The variant with no fields and the variant with two fields round-trip just fine.

fn test_contributor_deserialize() {
    use serde::{Deserialize, Serialize};
    use std::net::{IpAddr, Ipv4Addr};
    let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));

    #[track_caller]
    fn assert_round_trip<T: Serialize + serde::de::DeserializeOwned + std::fmt::Debug + Eq>(
        val: T,
    ) {
        let cbor = serde_cbor::to_vec(&val).unwrap();
        assert_eq!(serde_cbor::from_slice::<T>(&cbor).unwrap(), val);
    }

    #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
    struct IpContributor {
        ip: IpAddr,
    }

    #[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
    #[serde(untagged)]
    pub enum Contributor {
        Deleted,
        Ip { ip: IpAddr },
        User { username: String, id: u32 },
    }

    assert_round_trip(Contributor::Deleted);
    assert_round_trip(Contributor::User {
        username: "Wonderfool".into(),
        id: 1,
    });

    assert_round_trip(IpContributor { ip });
    assert_round_trip(Contributor::Ip { ip });
}

This comes from an in-development version of this crate.