PackageTrack
Sign in Get early access

deku

bit level serialization/deserialization proc-macro for structs

0.20.3 7.4M downloads/mo #3669 most downloaded on crates.io sharksforarms/deku

What this package is like to depend on

Last release 7 months ago

15 Jan 2026

Release timing varies

gaps range from 4 weeks to 1.2 years

Most releases are documented

notes for 30 of 34 stable releases

14 versions withdrawn

withdrawn after publishing

6 years old

48 releases · first in 2020

4 releases in the last 12 months

see the full history below

Release timeline

48 releases · Mar 2020 to Jan 2026
2021 2022 2023 2024 2025 2026
Release Pre-release Withdrawn

Releases

latest 48
  1. 0.20.3 15 Jan 2026
    Release notes

    Fixed

    • DekuSize: Add padding size calculation (#640)
    • DekuSize: Add magic enum/struct field/top-level (#639)
    • DekuSize: Disallow seek attributes for struct/enums and fields (#638)
    Open source →
    Release notes

    Fixed

    • DekuSize: Add padding size calculation (#640)
    • DekuSize: Add magic enum/struct field/top-level (#639)
    • DekuSize: Disallow seek attributes for struct/enums and fields (#638)
    Open source →
  2. 0.20.2 25 Nov 2025
    Release notes

    Other

    • Fix recursive DekuSize impl (#628)
    Open source →
    Release notes

    Other

    • Fix recursive DekuSize impl (#628)
    Open source →
  3. 0.20.1 25 Nov 2025
    Release notes

    Added

    • Add DekuSize impl (#618)

    Other

    • Uphold alignment requirements for use of Seek (#625)
    • Improved documentation on how endian etc. interacts with ctx (#623)
    • Lift alloc requirement for bits feature (#614)
    Open source →
    Release notes

    Added

    • Add DekuSize impl (#618)

    Other

    • Uphold alignment requirements for use of Seek (#625)
    • Improved documentation on how endian etc. interacts with ctx (#623)
    • Lift alloc requirement for bits feature (#614)
    Open source →
  4. 0.20.0 15 Oct 2025
    Release notes

    Fixed

    • remove unsafe slice MaybeUninit::uninit().assume_init() (#601)

    Added

    • The alloc feature, allowing use in environments lacking a heap #582
    • The descriptive-errors feature, replacing no-assertion-string #582

    Other

    • update deps (#612)
    • Fix #571: Add more documentation about ctx in the first example (#574)
    • introduce release-plz
    • Fix reading little endian fields in LSB order when not aligned to byte boundaries (#604)
    • Ensure bits fit in container (#598)
    • Fix big endian bit_order lsb writing (#597)
    • Improve error message for id_type and missing repr (#596)
    • Fix bit order padding logic in Writer::finalize and update tests (#595)
    • Expose alloc as a selectable feature (#582)
    • Removed duplicate bits entry from the 'List of attributes' section of attributes docs (#588)
    • Fix DekuRead for #[repr(...)] enums constructed using id via ctx and whose variants assign discriminant values (#577)
    • Change arc/cow/cstring requirements from std to alloc (#579)
    • deku_read: Use checked slice for remaining data (#581)
    • Implements From for no_std_io::io::Error in no_std context (#578)
    • Warnings and clippy fixes (#575)
    • hashset: tests: Handle arbitrary iteration order of HashSet (#573)
    • add map attribute to list (#570)
    • Return empty vec for read_to_end ZST (#566)
    • Bugfix/signed values in bitfields (#565)
    • Fix writer dropping count of bytes written for unaligned writes (#561)
    • Fix CString byte length reading (#563)
    Open source →
    Release notes

    Fixed

    • remove unsafe slice MaybeUninit::uninit().assume_init() (#601)

    Other

    • update deps (#612)
    • Fix #571: Add more documentation about ctx in the first example (#574)
    • introduce release-plz
    • Fix reading little endian fields in LSB order when not aligned to byte boundaries (#604)
    • Ensure bits fit in container (#598)
    • Fix big endian bit_order lsb writing (#597)
    • Improve error message for id_type and missing repr (#596)
    • Fix bit order padding logic in Writer::finalize and update tests (#595)
    • Expose alloc as a selectable feature (#582)
    • Removed duplicate bits entry from the 'List of attributes' section of attributes docs (#588)
    • Fix DekuRead for #[repr(...)] enums constructed using id via ctx and whose variants assign discriminant values (#577)
    • Change arc/cow/cstring requirements from std to alloc (#579)
    • deku_read: Use checked slice for remaining data (#581)
    • Implements From<DekuError> for no_std_io::io::Error in no_std context (#578)
    • Warnings and clippy fixes (#575)
    • hashset: tests: Handle arbitrary iteration order of HashSet (#573)
    • add map attribute to list (#570)
    • Return empty vec for read_to_end ZST (#566)
    • Bugfix/signed values in bitfields (#565)
    • Fix writer dropping count of bytes written for unaligned writes (#561)
    • Fix CString byte length reading (#563)
    Open source →
  5. 0.19.1 22 May 2025
    Release notes

    What's Changed

    Full Changelog: deku-v0.19.0...deku-v0.19.1

    Open source →
  6. 0.19.0 25 Apr 2025 withdrawn
    Release notes

    Features

    Added bit_order (#483)

    After much development, bit_order is now a supported attribute! Msb is still the default bit-order for all operations,
    but if you need Lsb ordering, deku now has you covered.

    For example, the following is now possible:

    # #[derive(Debug, DekuRead, DekuWrite, PartialEq)]
    #[deku(bit_order = "lsb")] // <--
    pub struct SquashfsV3 {
        #[deku(bits = "4")]
        inode_type: u8,
        #[deku(bits = "12")]
        mode: u16,
        uid: u8,
        guid: u8,
        mtime: u32,
        inode_number: u32,
    }
    let data: &[u8] = &[
    //       inode_type
    //     ╭-----------
    //     |
    //     |    mode
    //    ╭+--------   ...and so on
    //    ||    ||
    //    vv    vv
        0x31, 0x12, 0x04, 0x05, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
    ];

    If you were using our internal reader the following changed. As well as the leftover field now containing ordering.

    - reader.read_bytes(exact.0, &mut bytes)?;
    + reader.read_bytes(exact.0, &mut bytes, Order::Lsb0)?;

    Added bytes ctx for CString (#497)

    #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    pub struct Data {
        len: u8,
        #[deku(bytes = "*len as usize")]
        s: CString,
    }

    Changed id_pat (#540)

    The id_pat attribute has been restored to the behavior of 0.16.0, removing the seek and re-read.

    Allow token streams for bytes attribute (#489)

    # #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    struct DekuTest {
        field_a_size: u8,
        #[deku(bytes = "*field_a_size as usize")]
        field_a: u32,
    }

    Updates

    • Arc support by @vhdirk (#522)
    • Update no-std-io2 to 0.9.0 and Updated MSRV to 1.81 (#529)
    • Add field support for magic attribute (#503)
    • Add NoSeek type for unseekable Read + Write impls (#487)
    • Add performance specializations for count attribute + Vec<u8>(#481)
    • Reader may now take ownership of Read + Seek type. Thanks @wgreenburg (#521).

    Fixes

    • Fix pad_* attributes in no_std (#478)
    • Fix bug with id_pat and read_bytes_const (#479)
    • Several fixes for scope and imports in proc-macros, thanks @Serial-ATA (#541, #538, #539)
    Open source →
  7. 0.18.1 09 Sep 2024

    Nothing published for this version

  8. 0.18.0 07 Sep 2024
    Release notes

    Usability

    • Reading now requires Seek. Attributes such as seek_from_start, seek_from_current, seek_from_end, and seek_rewind were added to be able to control the position of the reader before reading a field (#360)
    • Support added for unit structs (#450)
    • to_slice was added to write an to a slice (#461)

    Performance

    • The use of bits parsing is now an optional feature. If bit-level parsing is not useful for your application, you can disable it to get some performance benefits. (#446)
    • Performance of read_all was improved (#441)

    Enum improvements

    • Added id_endian attribute to specify the endianness of id (#476)
    • Support for bool literals in enum id attribute (#472)
    • id_pat attribute was re-introduced (#454)
    Open source →
    Release notes

    Usability

    • Reading now requires Seek. Attributes such as seek_from_start, seek_from_current, seek_from_end, and seek_rewind were added to be able to control the position of the reader before reading a field (#360)
    • Support added for unit structs (#450)
    • to_slice was added to write an to a slice (#461)

    Performance

    • The use of bits parsing is now an optional feature. If bit-level parsing is not useful for your application, you can disable it to get some performance benefits. (#446)
    • Performance of read_all was improved (#441)

    Enum improvements

    • Added id_endian attribute to specify the endianness of id (#476)
    • Support for bool literals in enum id attribute (#472)
    • id_pat attribute was re-introduced (#454)
    Open source →
  9. 0.17.0 23 May 2024
    Release notes

    Changes

    • Bumped MSRV to 1.71 (#438)
    • Add DekuWrite impl for [T] (#416)
    • Add no-assert-string feature to remove panic string on failed assertion (#405)
    • Add read_all attribute to read until reader.end() (#387)
    • Changed edition to 2021 (#389)
    • Refactored logging feature with massive usability increases (#352), (#355)
    • Bumped the syn library to 2.0, which required replacing type for Enums with id_type (#386)
     #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    -#[deku(type = "u8")]
    +#[deku(id_type = "u8")]
     enum DekuTest {
         #[deku(id_pat = "_")]
         VariantC((u8, u8)),
     }

    Updated Reader API

    • Changed API of reading to use io::Read, bringing massive performance and usability improvements (#352)
    • Changed the trait DekuRead to DekuReader

    For example:

    use std::io::{Seek, SeekFrom, Read};
    use std::fs::File;
    use deku::prelude::*;
    
    #[derive(Debug, DekuRead, DekuWrite, PartialEq, Eq, Clone, Hash)]
    #[deku(endian = "big")]
    struct EcHdr {
        magic: [u8; 4],
        version: u8,
        padding1: [u8; 3],
    }
    
    let mut file = File::options().read(true).open("file").unwrap();
    let ec = EcHdr::from_reader((&mut file, 0)).unwrap();
    • The more internal (with context) read(..) was replaced with from_reader_with_ctx(..).
      With the switch to internal streaming, the variables deku::input, deku::input_bits, and deku::rest are now not possible and were removed.
      deku::reader is a replacement for some of the functionality.
      See examples/deku_input.rs for a new example of caching all reads.

    Old:

    #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    struct DekuTest {
        field_a: u8,
    
        #[deku(
            reader = "bit_flipper_read(*field_a, deku::rest, BitSize(8))",
        )]
        field_b: u8,
    }
    
    fn custom_read(
        field_a: u8,
        rest: &BitSlice<u8, Msb0>,
        bit_size: BitSize,
    ) -> Result<(&BitSlice<u8, Msb0>, u8), DekuError> {
    
        // read field_b, calling original func
        let (rest, value) = u8::read(rest, bit_size)?;
    
        Ok((rest, value))
    }

    New:

    #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    struct DekuTest {
        field_a: u8,
    
        #[deku(
            reader = "bit_flipper_read(*field_a, deku::reader, BitSize(8))",
        )]
        field_b: u8,
    }
    
    fn custom_read<R: std::io::Read>(
        field_a: u8,
        reader: &mut Reader<R>,
        bit_size: BitSize,
    ) -> Result<u8, DekuError> {
    
        // read field_b, calling original func
        let value = u8::from_reader_with_ctx(reader, bit_size)?;
    
        Ok(value)
    }
    • With the addition of using Read, containing a byte slice with a reference is not supported:

    Old

    #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    struct TestStruct<'a> {
        bytes: u8,
    
        #[deku(bytes_read = "bytes")]
        data: &'a [u8],
    }

    New

    #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    struct TestStruct {
        bytes: u8,
    
        #[deku(bytes_read = "bytes")]
        data: Vec<u8>,
    }
    • id_pat is now required to be the same type as stored id.
      This also disallows using tuples for storing the id:

    Old:

    #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    #[deku(id_type = "u8")]
    enum DekuTest {
        #[deku(id_pat = "_")]
        VariantC((u8, u8)),
    }

    New:

    #[derive(PartialEq, Debug, DekuRead, DekuWrite)]
    #[deku(id_type = "u8")]
    enum DekuTest {
        #[deku(id_pat = "_")]
        VariantC {
            id: u8,
            other: u8,
        },
    }
    • The feature const_generics was removed and is enabled by default.

    Updated Writer API

    • Changed API of writing to use io::Write, bringing massive performance and usability improvements (#355)
    • Changed the trait DekuWrite to DekuWriter
    • The more internal (with context) write(..) was replaced with to_writer(..).
      With the switch to internal streaming, the variables deku::output are now not possible and were removed. deku::writer is a replacement for some of the functionality.

    Old:

    fn bit_flipper_write(
        field_a: u8,
        field_b: u8,
        output: &mut BitVec<u8, Msb0>,
        bit_size: BitSize,
    ) -> Result<(), DekuError> {
        // Access to previously written fields
        println!("field_a = 0x{:X}", field_a);
    
        // value of field_b
        println!("field_b = 0x{:X}", field_b);
    
        // Size of the current field
        println!("bit_size: {:?}", bit_size);
    
        // flip the bits on value if field_a is 0x01
        let value = if field_a == 0x01 { !field_b } else { field_b };
    
        value.write(output, bit_size)
    }
    
    #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    struct DekuTest {
        field_a: u8,
    
        #[deku(
            writer = "bit_flipper_write(*field_a, *field_b, deku::output, BitSize(8))"
        )]
        field_b: u8,
    }

    New:

    fn bit_flipper_write<W: Write>(
        field_a: u8,
        field_b: u8,
        writer: &mut Writer<W>,
        bit_size: BitSize,
    ) -> Result<(), DekuError> {
        // Access to previously written fields
        println!("field_a = 0x{:X}", field_a);
    
        // value of field_b
        println!("field_b = 0x{:X}", field_b);
    
        // Size of the current field
        println!("bit_size: {:?}", bit_size);
    
        // flip the bits on value if field_a is 0x01
        let value = if field_a == 0x01 { !field_b } else { field_b };
    
        value.to_writer(writer, bit_size)
    }
    
    #[derive(Debug, PartialEq, DekuRead, DekuWrite)]
    struct DekuTest {
        field_a: u8,
    
        #[deku(
            writer = "bit_flipper_write(*field_a, *field_b, deku::writer, BitSize(8))"
        )]
        field_b: u8,
    }
    • Added DekuError::Write to denote io::Write errors

    Bug fix

    • Fix error for invalid deku_id generation on generic enum (#411)
    Open source →
  10. 0.16.0 28 Feb 2023
    Release notes

    Changes

    Bug fix

    Open source →
  11. 0.15.1 19 Dec 2022
    Release notes

    Small bug fix: Use fully qualified path when calling write as it may clash with other impls

    Open source →
  12. 0.15.0 16 Nov 2022
    Release notes

    Breaking/Performance

    • Upgrade to bitvec 1.0.0 may cause some breaking changes in some code bases.
    • Performance note: Upgrade to bitvec 1.0.0 has shown negative performance impacts.

    Changes

    Bug fix

    Open source →
  13. 0.14.1 09 Oct 2022
    Release notes

    Bug fix

    • Fix issue where endianness trickery wouldn't swap bytes correctly when reading less than the full amount into an integer (@caass) (#283)

    Changed

    Open source →
  14. 0.14.0 06 Oct 2022
    Release notes

    This release introduces a performance specialization/optimization in the read path for bytes

    Breaking

    • Size enum removed in favor of BitSize and ByteSize, this change is to allow a performance optimization in the byte reading
    • Byte specialization (@wcampbell0x2a) (#278)

    Added

    Open source →
  15. 0.13.1 09 Jun 2022
    Release notes

    🚨 NOTICE 🚨

    • Fixed undefined behavior in the use of MaybeUninit in slice implementation (#254)
    • Backported fix to 0.12 series as 0.12.6 and yanked affected versions (0.13.0, 0.12.5, 0.12.4)
    Open source →
  16. 0.13.0 27 Feb 2022 withdrawn
    Release notes

    Breaking

    Open source →
  17. 0.12.6 09 Jun 2022
    Release notes
    • (Backport) Fixed undefined behavior in the use of MaybeUninit in slice implementation (#254)
    Open source →
  18. 0.12.5 11 Nov 2021 withdrawn
    Release notes
    Open source →
  19. 0.12.4 11 Oct 2021 withdrawn
    Release notes
    Open source →
  20. 0.12.3 06 Jul 2021
    Release notes
    • Bug fix for structs/enums which also define a to_bytes function
    Open source →
  21. 0.12.2 15 Jun 2021
    Release notes
    • Bug fix for in primitive bitslice convertion (issue/commit)
    • Added Miri tests including testing on big endian target (#211)
    Open source →
  22. 0.12.1 25 May 2021
    Release notes
    • Add support for raw indentifiers (@Visse) (#221)
    • Dependency updates
    Open source →
  23. 0.12.0 13 Apr 2021
    Release notes

    Breaking

    • const_generics feature enabled by default

    Added

    • Add optional const_generics feature (@soruh) (#187)
      • This allows for reading/writing arrays with >32 elements when enabled
    • DekuRead+DekuWrite implementations for Cow<T> (@abungay) (#186)
    • DekuRead+DekuWrite implementations for HashMap (@abungay) (#199)
    • DekuRead+DekuWrite implementations for HashSet (@abungay) (#199)
    • DekuWrite implementations for &T (@abungay) (#199)
    • DekuRead+DekuWrite implementations for tuple (@abungay) (#198)

    Other

    Open source →
  24. 0.11.0 25 Feb 2021
    Release notes

    Breaking

    • Removed bitvec from deku::prelude (#181)
      • This will break custom reader and writer function definitions
      • bitvec is re-exported via: deku::bitvec:: (this contains bitvec::prelude::*)

    Added

    • Added DekuEnumExt to provide extra utility functions to enums. (#176)
      • This trait is implemented on enums derived with #[derive(DekuRead)]
      • This trait currently contains 1 function: deku_id()
      • deku_id can be called on an enum variant to get the deku id of the variant
    • Added Incomplete(NeedSize) variant on DekuError (#177)
    • Added CODE_OF_CONDUCT.md
    • Code improvements (@wcampbell0x2a)
    Open source →
  25. 0.10.1 25 Feb 2021
    Release notes
    Open source →
  26. 0.10.0 09 Jan 2021
    Release notes

    Breaking

    • Enum's which don't specify an id attribute now default to their discriminant value instead of being treated as a catch-all (#139)
    • Removed BitSize in favor of a new enum Size with two variants, Bits and Bytes (#138)
    • Added namespacing to internal variables. deku:: is used to access internal variables in token fields. (#150) For example, reader = "my_reader(deku::rest, deku::bit_offset)" or writer = "my_writer(deku::output)"
    • Introduced a lifetime to DekuRead in support of zero-copy reading (#158)

    Added

    • Zero-copy reading on &[u8] (#158)
    • Padding related attributes: pad_bits_before, pad_bytes_before, pad_bits_after, pad_bytes_after (#163)
    • Assertion related attributes: assert, assert_eq (#164)
    • Ability to use more types in enum's type attribute (#162)
    • Ability to use LitByteStr in enum's id attribute, for example id = b"0x01" (#162)
    • Access to read offset via bit_offset and byte_offset internal variables. (#149) These are accessed via deku:: namespace, deku::bit_offset and deku::byte_offset. (#150)
    • #[deku(temp)] attribute, enabled via deku_derive proc-macro attribute. (#136) This allows reading/use of a field without it being stored in the container.
    • DekuRead+DekuWrite implementations for CString (#144)
    • DekuRead+DekuWrite implementations for NonZeroT types (#140)
    • DekuRead+DekuWrite implementations for bool (#161)
    • DekuRead+DekuWrite implementations for () (#159)
    • DekuRead+DekuWrite implementations for Box<T> and Box<[T]> (#160)

    Other

    Open source →
  27. 0.9.3 14 Dec 2020
    Release notes
    Open source →
  28. 0.9.2 14 Dec 2020 withdrawn
    Release notes
    Open source →
  29. 0.9.1 31 Oct 2020
    Release notes
    • Changed minimum bitvec version to 0.19.4 to have desired offset_from functionality (https://github.com/myrrlyn/bitvec/issues/86). This was missed in 0.9.0 release.
    • Code improvements (@wcampbell0x2a)
    Open source →
  30. 0.9.0 30 Oct 2020
    Release notes
    • Added magic attribute, this allows the ability to specify a set of bytes which must be present at the start of the data (@samuelsleight)
    • Added until attribute, this allows the ability to read until a given predicate (@samuelsleight)
    • Added bits_read and bytes_read container attributes, this allows the ability to specify an amount of bits/bytes to read inside a Vec<T> (@samuelsleight)
    • Improved documentation
    • Refactored test cases
    • Code improvements (@wcampbell0x2a)
    Open source →
  31. 0.8.0 29 Sep 2020
    Release notes
    • write now takes a &mut BitVec instead of returning a BitVec, this optimization speeds up serialization (@agausmann)

    The following items have been renamed: (@wcampbell0x2a)

    • Renamed id_type in favor of type
    • Renamed id_bits in favor of bits
    • Renamed id_bytes in favor of bytes

    Internal:

    • Updated criterion to latest
    • Using tarpaulin for code coverage now
    • Swapped hex! macro (@inspier)
    • Code improvements (@wcampbell0x2a)
    Open source →
  32. 0.7.2 02 Sep 2020
    Release notes
    • Added ctx_default attribute, this allows the ability to specify defaults to types accepting a ctx if none are provided
    • Updated documentation regarding the concept of context and how it applies to some attributes
    • Added validation to id attribute
    • endian attribute now accepts an expression (still accepts big or little)
    • Updated bitvec dependency
    Open source →
  33. 0.7.1 31 Jul 2020
    Release notes
    • Added id attribute to top-level enums which allows to specify the enum id, for example a value coming via a context variable
    Open source →
  34. 0.7.0 28 Jul 2020
    Release notes
    • Added cond attribute which allows for conditional parsing or skipping of a field
    • Added id_pat attribute which allows pattern matching for enum variants

    Community:

    • Added ctx attribute which adds the ability to pass context to child parsers from the parent (@constfold)
    • Internal refactoring of endian, bits and count attributes, they are now sugar around the ctx (@constfold)
    • Renamed to_bitvec to to_bits (@wcampbell0x2a)
    Open source →
  35. 0.6.1 06 Jul 2020
    Release notes
    • Enum variant specified without an id attribute is now considered the catch-all
    Open source →
  36. 0.6.0 22 Jun 2020
    Release notes
    • Added DekuContainerRead and DekuContainerWrite to expose from_bytes, to_bytes and to_bitvec
    • Added release.toml
    • Added CHANGELOG.md to track changes
    Open source →
  37. 0.5.2 18 Jun 2020

    Nothing published for this version

  38. 0.5.1 12 Jun 2020

    Nothing published for this version

  39. 0.5.0 11 Jun 2020

    Nothing published for this version

  40. 0.4.1 10 Jun 2020 withdrawn

    Nothing published for this version

  41. 0.4.0 08 Jun 2020 withdrawn

    Nothing published for this version

  42. 0.3.1 03 Jun 2020 withdrawn

    Nothing published for this version

  43. 0.3.0 01 Jun 2020 withdrawn

    Nothing published for this version

  44. 0.2.0 29 May 2020 withdrawn

    Nothing published for this version

  45. 0.1.4 28 May 2020 withdrawn

    Nothing published for this version

  46. 0.1.3 28 May 2020 withdrawn

    Nothing published for this version

  47. 0.1.2 30 Mar 2020 withdrawn

    Nothing published for this version

  48. 0.1.1 20 Mar 2020 withdrawn

    Nothing published for this version

Every package, every release, already written down.

The archive is open and free. Watching your own project is what we are building next.

Browse the archive