deku icon indicating copy to clipboard operation
deku copied to clipboard

Request for Enhancement: Ability to use versions of data types

Open v1gnesh opened this issue 3 years ago • 1 comments

Going through the attributes page, I see that we can use a combo of skip, cond, and default to essentially achieve this.

Looking at the versionize crate, I've just realized that support for versions in deku will yet again save me pages of almost-fully-duplicate code.

For the same use case described here... deku has saved me from manually writing out hundreds of impl blocks and a horde of read_be_bytes/read_le_bytes within each of them. #213 will remove the need for high hundreds of #[deku(...)] tagged with struct fields. #217 will remove the need for hundreds of #[deku(endian="little/big")] tagged to each struct/enum.

This feature of having versions will save me from having to duplicate all of the above (due to minor variations to many struct fields).

I'm all for higher level of control (keeping things at the field level) as you've suggested in the #213. If it weren't for deku, I'd have had to roll hundreds of impl blocks... More generic controls, I'm sure, will help the user do more by keep the lib usage/invocations simple, leaving the heavy lifting to the parser.

v1gnesh avatar May 22 '21 13:05 v1gnesh

Could the crate be used with deku? This seems like it's solving a different use case.

Deku can achieve versioning via enums: https://docs.rs/deku/0.12.0/deku/attributes/index.html#id-variant

Could you provide an example of how you'd envision it with deku?

sharksforarms avatar May 22 '21 16:05 sharksforarms

Could the crate be used with deku?

It says it currently only supports bincode back-end, so probably not.

This seems like it's solving a different use case.

Yeah, I suppose it is to struct/enum what versioned schema is to a database.

Deku can achieve versioning via enums

Yeah, I use this. However, versioning will help at a higher level. Speaking of which.. I have something like:

enum Body {
  #[deku(id=1)]
  Type1(os::os_2.4::Type1),
  #[deku(id=2)]
  Type2(os::os_2.4::Type2),
  ...
  #[deku(id=125)]
  Type125(os::os_2.4::Type125),

.. but that's for choosing the type of the whole record.

Could you provide an example of how you'd envision it with deku?

In this link, scrolling down to chapter 17 in the index in the left, you'll see the different types. This book is for one version of the OS. Say I have a project which looks like this:

project
|__ Cargo.toml
|__ src/
    |__ main.rs
    |__ common.rs
    |__ products/
    |   |__ mod.rs
    |   |__ prodA_v6.rs
    |   |__ prodA_v7.rs
    |   |__ prodB_v5.rs
    |   |__ prodC_v9.rs
    |__ os/
        |__ mod.rs
        |__ os_2.4.rs
        |__ os_2.3.rs

All the different types & sub-types mentioned in the book, they'll all come in os_2.4.rs. If you look at page xxiii in the same link, titled 'Summary of changes', you'll see that the types keep getting updated, i.e., mostly, new fields being added.

os_2.3.rs and os_2.4.rs will have the same content 85+% of the time. But, they have to be duplicated in separate files to differentiate & to maintain control. If versions were available, I can instead maintain just one file. Versions can be used to clearly document/tag fields as to when they were introduced, and use new fields in new versions, as they're being added.

Going to page 284 of this doco, 'triplet section' (bottom of that page extending into the next one), you'll see that the last 3 fields are added newly. The first field gives away the length of the total section. Knowing that, how can I use deku to conditionally look at the newly added fields?

Sorry, I know I haven't put it together for easy understanding. I hope the above info is helpful. I can't give a more concrete example at the moment as I haven't started building out structs for most of these types, especially the complicated ones.

v1gnesh avatar May 23 '21 11:05 v1gnesh