Hello! I encountered this while exploring the use of CBOR as an alternative to JSON for something I'm working on. My project will require moving around a bunch of floating point numbers, and if I can I'd prefer to avoid the precision loss of converting them to text and back as JSON does. Unfortunately, I also can't guarantee that the two sides of the communication will be running the same code, so I need some flexibility to evolve the messages without breaking things. CBOR seems to fit that bill quite nicely!
However, I did find something odd:
#[derive(Debug, serde_derive::Serialize, serde_derive::Deserialize)]
#[serde(tag = "event")]
pub enum EnumMessage {
Message { value: f64 },
}
#[derive(Debug, serde_derive::Serialize, serde_derive::Deserialize)]
struct Message {
value: f64,
}
#[test]
fn test_roundtrip_cbor_enum() {
let val = EnumMessage::Message { value: 3f64 };
let bytes = serde_cbor::to_vec(&val).unwrap();
let new_val: EnumMessage = serde_cbor::from_slice(&bytes).unwrap();
}
#[test]
fn test_roundtrip_cbor_struct() {
let val = Message { value: 3f64 };
let bytes = serde_cbor::to_vec(&val).unwrap();
let new_val: Message = serde_cbor::from_slice(&bytes).unwrap();
}
The enum test fails with this error message:
thread 'test_roundtrip_cbor_enum' panicked at 'called `Result::unwrap()` on an `Err` value: ErrorImpl { code: Message("invalid type: floating point `3`, expected f64"), offset: 0 }', tests/criterion_tests.rs:559:32
As a workaround, removing the tag from the enum allows it to deserialize just fine.