`default_on_eof` does not always work when nested
I had been scratching my head at a default_on_eof not working (error: eof) and was finally able to reproduce.
#[derive(PartialEq, Debug, Readable, Writable)]
enum DerivedEnumWithNestedDefaultOnEof {
First {
b: u8,
#[speedy(default_on_eof)]
c: u8
},
Second {
a: u8,
nested: DerivedStructWithVecWithCountWithDefaultOnEof,
e: RangeInclusive< u8 >
},
Third {
d: u8
}
}
#[derive(PartialEq, Debug, Readable, Writable)]
struct DerivedStructWithVecWithCountWithDefaultOnEof {
length: u8,
#[speedy(length = length, default_on_eof)]
data: Vec< u8 >
}
// test
let deserialized: DerivedEnumWithNestedDefaultOnEof = Readable::read_from_buffer_with_ctx( Endianness::LittleEndian, &[1, 0, 0, 0, 0xAA, 2, 0, 0] ).unwrap();
assert_eq!( deserialized, DerivedEnumWithNestedDefaultOnEof::Second { a: 0xAA, nested: DerivedStructWithVecWithCountWithDefaultOnEof { length: 2, data: vec![] }, e: 0..=0 } );
// thread 'test_derived_struct_with_default_on_eof' panicked at ...
It makes sense! Ultimately, putting a default_on_eof in a nested struct and then defining other mandatory fields on the parent struct is similar to adding a default_on_eof on a field that's not the last.
In this particular example (not the smallest repro) of a buffer being read from: &[1, 0, 0, 0, 0xAA, 2, 0, 0]:
- enum tag (
Second) - u8 (
a: 0xAA) - u8 (
length: 2) - Vec (
data: vec![0, 0]) - EOF
The reader was expecting a RangeInclusive<u8> at this point, but there's nothing because it read the bytes into the Vec<u8>.
I'm not sure what the solution is here. I don't think there's any way for speedy to do the correct thing. I'm also not sure there's a way to disallow nesting a struct that has default_on_eof without it being the last field of the parent struct. If there is, that might throw a helpful error to the user.