Skip to content

default_on_eof does not always work when nested #77

@jeromegn

Description

@jeromegn

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions