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 2026Releases
latest 48-
0.20.315 Jan 2026 -
0.20.225 Nov 2025 -
0.20.125 Nov 2025 -
0.20.015 Oct 2025Release notes
Open source →Fixed
- remove unsafe slice MaybeUninit::uninit().assume_init() (#601)
Added
- The
allocfeature, allowing use in environments lacking a heap #582 - The
descriptive-errorsfeature, replacingno-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
allocas a selectable feature (#582) - Removed duplicate
bitsentry from the 'List of attributes' section of attributes docs (#588) - Fix DekuRead for #[repr(...)] enums constructed using
idviactxand 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)
Release notes
Open source →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
allocas a selectable feature (#582) - Removed duplicate
bitsentry from the 'List of attributes' section of attributes docs (#588) - Fix DekuRead for #[repr(...)] enums constructed using
idviactxand 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)
-
0.19.122 May 2025Release notes
Open source →What's Changed
- Add missing alloc::vec by @wcampbell0x2a in #550
- fix: fix and test of conditional fields depending on conditional fields by @goto40 in #555
- Support ipaddr in no-std by @wcampbell0x2a in #557
- Force repr attribute required for enum discr by @wcampbell0x2a in #554
- Prep release 0.19.1 by @sharksforarms in #559
Full Changelog: deku-v0.19.0...deku-v0.19.1
-
0.19.025 Apr 2025 withdrawnRelease notes
Open source →Features
Added
bit_order(#483)After much development,
bit_orderis now a supported attribute!Msbis still the default bit-order for all operations,
but if you needLsbordering, 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
readerthe following changed. As well as theleftoverfield 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_patattribute has been restored to the behavior of0.16.0, removing the seek and re-read.Allow token streams for
bytesattribute (#489)# #[derive(Debug, PartialEq, DekuRead, DekuWrite)] struct DekuTest { field_a_size: u8, #[deku(bytes = "*field_a_size as usize")] field_a: u32, }
Updates
Arcsupport by @vhdirk (#522)- Update
no-std-io2to 0.9.0 and UpdatedMSRVto1.81(#529) - Add field support for
magicattribute (#503) - Add
NoSeektype for unseekableRead+Writeimpls (#487) - Add performance specializations for
countattribute +Vec<u8>(#481) Readermay now take ownership ofRead + Seektype. Thanks @wgreenburg (#521).
Fixes
-
0.18.109 Sep 2024Nothing published for this version
-
0.18.007 Sep 2024Release notes
Open source →Usability
- Reading now requires
Seek. Attributes such asseek_from_start,seek_from_current,seek_from_end, andseek_rewindwere added to be able to control the position of the reader before reading a field (#360) - Support added for unit structs (#450)
to_slicewas 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_allwas improved (#441)
Enum improvements
Release notes
Open source →Usability
- Reading now requires
Seek. Attributes such asseek_from_start,seek_from_current,seek_from_end, andseek_rewindwere added to be able to control the position of the reader before reading a field (#360) - Support added for unit structs (#450)
to_slicewas 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_allwas improved (#441)
Enum improvements
- Reading now requires
-
0.17.023 May 2024Release notes
Open source →Changes
- Bumped MSRV to
1.71(#438) - Add DekuWrite impl for
[T](#416) - Add
no-assert-stringfeature to remove panic string on failed assertion (#405) - Add
read_allattribute to read untilreader.end()(#387) - Changed edition to 2021 (#389)
- Refactored
loggingfeature with massive usability increases (#352), (#355) - Bumped the
synlibrary to 2.0, which required replacingtypefor Enums withid_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
DekuReadtoDekuReader
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 withfrom_reader_with_ctx(..).
With the switch to internal streaming, the variablesdeku::input,deku::input_bits, anddeku::restare now not possible and were removed.
deku::readeris 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_patis 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_genericswas 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
DekuWritetoDekuWriter - The more internal (with context)
write(..)was replaced withto_writer(..).
With the switch to internal streaming, the variablesdeku::outputare now not possible and were removed.deku::writeris 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::Writeto denoteio::Writeerrors
Bug fix
- Fix error for invalid deku_id generation on generic enum (#411)
- Bumped MSRV to
-
0.16.028 Feb 2023Release notes
Open source →Changes
- Faster build times: Optimize derive macros (@dullbananas) (#320)
- Support for multiple arguments in enum
id(@wcampbell0x2a) (#315)
Bug fix
- Fixes #264 reported by wildbook: Drop MaybeUninit when failing to read entire slice (@wcampbell0x2a) (#317)
-
0.15.119 Dec 2022Release notes
Open source →Small bug fix: Use fully qualified path when calling
writeas it may clash with other impls -
0.15.016 Nov 2022Release notes
Open source →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
- Upgrade to bitvec 1.0.0 (@JuanPotato & @wcampbell0x2a) (#281)
- impl From<DekuError> for std::io::Error (@caass) (#285)
- Fix typo in docs (@vidhanio) (#291)
Bug fix
- Fix regression with unaligned u8 (@wcampbell0x2a) (#294)
-
0.14.109 Oct 2022Release notes
Open source →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
- Constify primitive bit size of types (@wcampbell0x2a) (#279)
-
0.14.006 Oct 2022Release notes
Open source →This release introduces a performance specialization/optimization in the read path for bytes
Breaking
Sizeenum removed in favor ofBitSizeandByteSize, this change is to allow a performance optimization in the byte reading- Byte specialization (@wcampbell0x2a) (#278)
Added
- Add logging feature (@wcampbell0x2a) (#271)
-
0.13.109 Jun 2022Release notes
Open source →- Documentation fix for
Size::byte_size(@korrat) (#261) - Derive
CloneonDekuError(@interruptinuse) (#255)
🚨 NOTICE 🚨
- Fixed undefined behavior in the use of
MaybeUninitin 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)
- Documentation fix for
-
0.13.027 Feb 2022 withdrawnRelease notes
Open source → -
0.12.609 Jun 2022Release notes
Open source →- (Backport) Fixed undefined behavior in the use of
MaybeUninitin slice implementation (#254)
- (Backport) Fixed undefined behavior in the use of
-
0.12.511 Nov 2021 withdrawn -
0.12.411 Oct 2021 withdrawn -
0.12.306 Jul 2021 -
0.12.215 Jun 2021 -
0.12.125 May 2021 -
0.12.013 Apr 2021Release notes
Open source →Breaking
const_genericsfeature enabled by default
Added
- Add optional
const_genericsfeature (@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
- Updated dependencies
- Updated wasm example
- Fix: Parenthesize pad/update attributes (@wcampbell0x2a) (#195)
- Fixed failing code coverage (@abungay) (#200)
- Update DekuRead documentation (@caass) (fcfdc24/#196)
- Updated hexlit dependency (@inspier) (#189)
- Refactoring and code improvements (@wcampbell0x2a)
-
0.11.025 Feb 2021Release notes
Open source →Breaking
- Removed
bitvecfromdeku::prelude(#181)- This will break custom
readerandwriterfunction definitions bitvecis re-exported via:deku::bitvec::(this containsbitvec::prelude::*)
- This will break custom
Added
- Added
DekuEnumExtto 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_idcan be called on an enum variant to get the dekuidof the variant
- This trait is implemented on enums derived with
- Added
Incomplete(NeedSize)variant onDekuError(#177) - Added
CODE_OF_CONDUCT.md - Code improvements (@wcampbell0x2a)
- Removed
-
0.10.125 Feb 2021 -
0.10.009 Jan 2021Release notes
Open source →Breaking
- Enum's which don't specify an
idattribute now default to their discriminant value instead of being treated as a catch-all (#139) - Removed
BitSizein favor of a new enumSizewith two variants,BitsandBytes(#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)"orwriter = "my_writer(deku::output)" - Introduced a lifetime to
DekuReadin 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
typeattribute (#162) - Ability to use LitByteStr in enum's
idattribute, for exampleid = b"0x01"(#162) - Access to read offset via bit_offset and byte_offset internal variables. (#149)
These are accessed via
deku::namespace,deku::bit_offsetanddeku::byte_offset. (#150) #[deku(temp)]attribute, enabled viadeku_deriveproc-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
- Internal code/test refactoring
- Code improvements (@myrrlyn, @wcampbell0x2a, @inspier)
- Enum's which don't specify an
-
0.9.314 Dec 2020 -
0.9.214 Dec 2020 withdrawn -
0.9.131 Oct 2020Release notes
Open source →- Changed minimum bitvec version to 0.19.4 to have desired
offset_fromfunctionality (https://github.com/myrrlyn/bitvec/issues/86). This was missed in 0.9.0 release. - Code improvements (@wcampbell0x2a)
- Changed minimum bitvec version to 0.19.4 to have desired
-
0.9.030 Oct 2020Release notes
Open source →- Added
magicattribute, this allows the ability to specify a set of bytes which must be present at the start of the data (@samuelsleight) - Added
untilattribute, this allows the ability to read until a given predicate (@samuelsleight) - Added
bits_readandbytes_readcontainer 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)
- Added
-
0.8.029 Sep 2020Release notes
Open source →writenow takes a&mut BitVecinstead of returning a BitVec, this optimization speeds up serialization (@agausmann)
The following items have been renamed: (@wcampbell0x2a)
- Renamed
id_typein favor oftype - Renamed
id_bitsin favor ofbits - Renamed
id_bytesin favor ofbytes
Internal:
- Updated criterion to latest
- Using tarpaulin for code coverage now
- Swapped hex! macro (@inspier)
- Code improvements (@wcampbell0x2a)
-
0.7.202 Sep 2020Release notes
Open source →- Added
ctx_defaultattribute, this allows the ability to specify defaults to types accepting actxif none are provided - Updated documentation regarding the concept of context and how it applies to some attributes
- Added validation to
idattribute endianattribute now accepts an expression (still acceptsbigorlittle)- Updated bitvec dependency
- Added
-
0.7.131 Jul 2020Release notes
Open source →- Added
idattribute to top-level enums which allows to specify the enum id, for example a value coming via a context variable
- Added
-
0.7.028 Jul 2020Release notes
Open source →- Added
condattribute which allows for conditional parsing or skipping of a field - Added
id_patattribute which allows pattern matching for enum variants
Community:
- Added
ctxattribute which adds the ability to pass context to child parsers from the parent (@constfold) - Internal refactoring of
endian,bitsandcountattributes, they are now sugar around thectx(@constfold) - Renamed
to_bitvectoto_bits(@wcampbell0x2a)
- Added
-
0.6.106 Jul 2020Release notes
Open source →- Enum variant specified without an
idattribute is now considered the catch-all
- Enum variant specified without an
-
0.6.022 Jun 2020Release notes
Open source →- Added
DekuContainerReadandDekuContainerWriteto exposefrom_bytes,to_bytesandto_bitvec - Added
release.toml - Added
CHANGELOG.mdto track changes
- Added
-
0.5.218 Jun 2020Nothing published for this version
-
0.5.112 Jun 2020Nothing published for this version
-
0.5.011 Jun 2020Nothing published for this version
-
0.4.110 Jun 2020 withdrawnNothing published for this version
-
0.4.008 Jun 2020 withdrawnNothing published for this version
-
0.3.103 Jun 2020 withdrawnNothing published for this version
-
0.3.001 Jun 2020 withdrawnNothing published for this version
-
0.2.029 May 2020 withdrawnNothing published for this version
-
0.1.428 May 2020 withdrawnNothing published for this version
-
0.1.328 May 2020 withdrawnNothing published for this version
-
0.1.230 Mar 2020 withdrawnNothing published for this version
-
0.1.120 Mar 2020 withdrawnNothing published for this version