Optional fields are not optional if they are introduced via generics
If a struct contains a field declared to be of type Option<Foo>, then #[derive(Decode)] implements code that decodes to Some(Foo) if the field is present in the CBOR source material, or None if it is absent. This agrees with the minicbor_derive documentation which states “Optional types default to None if their value is not present during decoding.”
If a struct contains a field declared to be of generic type T, and T happens to be Option<Foo>, then #[derive(Decode)] implements code that fails if the field is not present in the source material.
It would be nice if the latter case worked like the former case. A demonstration follows, in which the first decode call succeeds and the second fails, despite ultimately trying to decode two structs with identical fields in them:
use minicbor::{Decode, Encode};
#[derive(Encode)]
#[cbor(array)]
struct Source(#[n(0)] bool);
#[derive(Decode, Debug)]
#[cbor(array)]
struct Specific(#[b(0)] pub bool, #[b(1)] pub Option<u32>);
#[derive(Decode, Debug)]
#[cbor(array)]
struct Generic<T, U>(#[b(0)] pub T, #[b(1)] pub U);
fn main() {
let mut buffer = Vec::<u8>::new();
minicbor::encode(&Source(true), &mut buffer).unwrap();
println!("{:?}", buffer);
let d = minicbor::decode::<Specific>(&buffer).unwrap();
println!("{:?}", d);
let d = minicbor::decode::<Generic<bool, Option<u32>>>(&buffer).unwrap();
println!("{:?}", d);
}
I’m not sure how practical it is, though.