- The
allocfeature, allowing use in environments lacking a heap #582 - The
descriptive-errorsfeature, replacingno-assertion-string#582
0.19.1 - 2025-05-22
- Support IpAddr in nostd #557
- Require repr when using enum discriminant to avoid panic #554
- Fix and test of conditional temporary fields depending on conditional temporary fields (did not compile before). See unittest.
0.19.0 - 2025-02-07
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,
}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).
- 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)
0.18.0 - 2024-08-07
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
- Added
id_endianattribute to specify the endianness ofid(#476) - Support for
boolliterals in enumidattribute (#472) id_patattribute was re-introduced (#454)
0.17.0 - 2024-04-23
- 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)),
}- 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.
- 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
- Fix error for invalid deku_id generation on generic enum (#411)
0.16.0 - 2023-02-28
- Faster build times: Optimize derive macros (@dullbananas) (#320)
- Support for multiple arguments in enum
id(@wcampbell0x2a) (#315)
- Fixes #264 reported by wildbook: Drop MaybeUninit when failing to read entire slice (@wcampbell0x2a) (#317)
0.15.1 - 2022-12-19
Small bug fix: Use fully qualified path when calling write as it may clash with other impls
0.15.0 - 2022-11-16
- 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.
- Upgrade to bitvec 1.0.0 (@JuanPotato & @wcampbell0x2a) (#281)
- impl From for std::io::Error (@caass) (#285)
- Fix typo in docs (@vidhanio) (#291)
- Fix regression with unaligned u8 (@wcampbell0x2a) (#294)
0.14.1 - 2022-10-09
- Fix issue where endianness trickery wouldn't swap bytes correctly when reading less than the full amount into an integer (@caass) (#283)
- Constify primitive bit size of types (@wcampbell0x2a) (#279)
0.14.0 - 2022-10-06
This release introduces a performance specialization/optimization in the read path for bytes
Sizeenum removed in favor ofBitSizeandByteSize, this change is to allow a performance optimization in the byte reading- Byte specialization (@wcampbell0x2a) (#278)
- Add logging feature (@wcampbell0x2a) (#271)
0.13.1 - 2022-06-09
- Documentation fix for
Size::byte_size(@korrat) (#261) - Derive
CloneonDekuError(@interruptinuse) (#255)
- 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)
0.13.0 - 2022-02-26
0.12.6 - 2022-06-09
- (Backport) Fixed undefined behavior in the use of
MaybeUninitin slice implementation (#254)
0.12.5 - 2021-11-11
- Show struct ident in assertion error message (@wcampbell0x2a) (#239)
0.12.4 - 2021-10-11
0.12.3 - 2021-07-06
- Bug fix for structs/enums which also define a
to_bytesfunction
0.12.2 - 2021-06-15
- Bug fix for in primitive bitslice convertion (issue/commit)
- Added Miri tests including testing on big endian target (#211)
0.12.1 - 2021-05-25
0.12.0 - 2021-04-13
const_genericsfeature enabled by default
- Add optional
const_genericsfeature (@soruh) (#187)- This allows for reading/writing arrays with >32 elements when enabled
- DekuRead+DekuWrite implementations for Cow (@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)
- 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.0 - 2020-02-25
- Removed
bitvecfromdeku::prelude(#181)- This will break custom
readerandwriterfunction definitions bitvecis re-exported via:deku::bitvec::(this containsbitvec::prelude::*)
- This will break custom
- 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)
0.10.1 - 2020-02-25
- Update bitvec dependency to fix build failures
0.10.0 - 2020-01-09
- 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)
- 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 and Box<[T]> (#160)
- Internal code/test refactoring
- Code improvements (@myrrlyn, @wcampbell0x2a, @inspier)
0.9.3 - 2020-12-14
- Patch release to fix semver break in darling, this has since been fixed
- Patch release to fix semver break in darling, this has since been fixed
0.9.1 - 2020-10-31
- Changed minimum bitvec version to 0.19.4 to have desired
offset_fromfunctionality (ferrilab/bitvec#86). This was missed in 0.9.0 release. - Code improvements (@wcampbell0x2a)
0.9.0 - 2020-10-30
- 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 (@samuelsleight) - Improved documentation
- Refactored test cases
- Code improvements (@wcampbell0x2a)
0.8.0 - 2020-09-29
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.2 - 2020-09-02
- 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
0.7.1 - 2020-07-31
- Added
idattribute to top-level enums which allows to specify the enum id, for example a value coming via a context variable
0.7.0 - 2020-07-28
- 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)
0.6.1 - 2020-07-06
- Enum variant specified without an
idattribute is now considered the catch-all
- Added
DekuContainerReadandDekuContainerWriteto exposefrom_bytes,to_bytesandto_bitvec - Added
release.toml - Added
CHANGELOG.mdto track changes