Skip to content

Commit bce3cba

Browse files
committed
Release v0.0.11: Refactor codec syntax and add PhantomCodec
- BREAKING: Simplified derive macro syntax (arrays/vectors) - Add PhantomCodec for constant values with zero bytes - Add BoxCodec support in derive macro - Remove FixedU8SliceCodec (use BytesCodec + PhantomCodec) - Update examples and documentation
1 parent 991a6e8 commit bce3cba

12 files changed

Lines changed: 234 additions & 148 deletions

File tree

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.0.11] - 2025-11-05
11+
12+
### Added
13+
- `PhantomCodec` - A codec that encodes/decodes constant values with zero bytes (useful for phantom data)
14+
- `BoxCodec` support in derive macro with `box` keyword
15+
- Phantom codec support in derive macro with `= expr` syntax for constant values
16+
- Improved codec builder syntax - more intuitive pipeline-based approach
17+
18+
### Changed
19+
- **Breaking**: Refactored derive macro syntax for codecs:
20+
- Arrays: `$arr[item]``item $arr`
21+
- Vectors: `$vec(item)[len]``item $vec[len]`
22+
- Better compose-ability and readability
23+
- Removed `FixedU8SliceCodec` in favor of `BytesCodec` with `PhantomCodec` for fixed lengths
24+
- Updated all examples to use new syntax
25+
- Updated documentation examples across all codec types
26+
- Improved codec table in main library documentation with syntax examples
27+
28+
### Removed
29+
- `FixedU8SliceCodec` (replaced by `BytesCodec(PhantomCodec)`)
30+
1031
## [0.0.10] - 2025-11-04
1132

1233
### Added
@@ -29,6 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2950
### Added
3051
- Previous releases before standardized changelog
3152

32-
[Unreleased]: https://github.com/m-ali-akbay/byten/compare/v0.0.10...HEAD
53+
[Unreleased]: https://github.com/m-ali-akbay/byten/compare/v0.0.11...HEAD
54+
[0.0.11]: https://github.com/m-ali-akbay/byten/compare/v0.0.10...v0.0.11
3355
[0.0.10]: https://github.com/m-ali-akbay/byten/compare/v0.0.9...v0.0.10
3456
[0.0.9]: https://github.com/m-ali-akbay/byten/releases/tag/v0.0.9

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ members = ["byten", "byten_derive"]
33
resolver = "3"
44

55
[workspace.package]
6-
version = "0.0.10"
6+
version = "0.0.11"
77
edition = "2024"
88
authors = ["Ali Akbay <maakbay@gmail.com>"]
99
license = "MIT OR Apache-2.0"

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ use std::ffi::CString;
117117
pub struct Directory {
118118
#[byten(CStr $own)]
119119
pub name: CString,
120-
#[byten($vec(Box<Entry>)[u16 $be])]
120+
#[byten(Entry box $vec[u16 $be])]
121121
pub entries: Vec<Box<Entry>>,
122122
}
123123

@@ -160,11 +160,13 @@ The `#[byten(...)]` attribute supports a flexible syntax for customizing encodin
160160

161161
- **Endianness**: `$be` (big-endian), `$le` (little-endian)
162162
- **Variable-length**: `$uvarbe` (variable-length unsigned, big-endian)
163-
- **Collections**: `$vec(T)[Length]`, `$arr[T]`
163+
- **Collections**: `T $vec[Length]`, `T $arr`
164164
- **Bytes**: `$bytes[Length]` for raw byte slices
165165
- **Strings**: `$utf8` for UTF-8 strings, `CStr` for C strings
166166
- **Ownership**: `$own` to decode into owned data (e.g., `String`, `Vec`)
167167
- **Optional**: `$opt` for `Option<T>` types with presence byte
168+
- **Boxing**: `box` for `Box<T>` types
169+
- **Phantom**: `= expr` for constant values with zero bytes
168170
- **Remaining**: `..` to consume rest of input
169171
- **Custom**: `{ expr }` for custom codec expressions
170172

byten/examples/archive.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use byten::{Decode, DecodeOwned, DefaultCodec, Encode, EncodeToVec as _, Measure
66
pub struct Directory {
77
#[byten(CStr $own)]
88
pub name: CString,
9-
#[byten($vec(Box<Entry>)[u16 $be])]
9+
#[byten(Entry box $vec[u16 $be])]
1010
pub entries: Vec<Box<Entry>>,
1111
}
1212

byten/examples/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use byten::{Decode, DecodeOwned, DefaultCodec, Encode, EncodeToVec as _, Measure
22

33
#[derive(Debug, DefaultCodec, Encode, Measure, DecodeOwned)]
44
pub struct Foo {
5-
#[byten($arr[u16 $uvarbe])]
5+
#[byten(u16 $uvarbe $arr)]
66
pub bar: [u16; 4],
77
}
88

byten/src/asis.rs

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -309,92 +309,6 @@ impl<const N: usize> Measurer for U8ArrayRefCodec<N> {
309309
}
310310
}
311311

312-
/// A codec for fixed-size slices of `u8`.
313-
///
314-
/// # Examples
315-
/// ```rust
316-
/// use byten::{FixedU8SliceCodec, Decoder, Encoder, FixedMeasurer, Measurer, DecodeError, EncodeError};
317-
///
318-
/// let slice: &[u8] = &[1, 2, 3, 4];
319-
/// let codec = FixedU8SliceCodec::new(4);
320-
///
321-
/// let mut encoded = [0u8; 4];
322-
/// let mut offset = 0;
323-
///
324-
/// codec.encode(slice, &mut encoded, &mut offset).unwrap();
325-
/// assert_eq!(offset, 4);
326-
///
327-
/// let mut decode_offset = 0;
328-
/// let decoded: &[u8] = codec.decode(&encoded, &mut decode_offset).unwrap();
329-
/// assert_eq!(decoded, slice);
330-
/// assert_eq!(decode_offset, 4);
331-
///
332-
/// let size = codec.measure(slice).unwrap();
333-
/// assert_eq!(size, 4);
334-
///
335-
/// let fixed_size = codec.measure_fixed();
336-
/// assert_eq!(fixed_size, 4);
337-
/// ```
338-
pub struct FixedU8SliceCodec(usize);
339-
340-
impl FixedU8SliceCodec {
341-
pub const fn new(length: usize) -> FixedU8SliceCodec {
342-
FixedU8SliceCodec(length)
343-
}
344-
}
345-
346-
impl<'encoded: 'decoded, 'decoded> Decoder<'encoded, 'decoded> for FixedU8SliceCodec {
347-
type Decoded = &'decoded [u8];
348-
fn decode(
349-
&self,
350-
encoded: &'encoded [u8],
351-
offset: &mut usize,
352-
) -> Result<Self::Decoded, error::DecodeError> {
353-
if *offset + self.0 > encoded.len() {
354-
return Err(error::DecodeError::EOF);
355-
}
356-
let slice = &encoded[*offset..*offset + self.0];
357-
*offset += self.0;
358-
Ok(slice)
359-
}
360-
}
361-
362-
impl Encoder for FixedU8SliceCodec {
363-
type Decoded = [u8];
364-
fn encode(
365-
&self,
366-
decoded: &Self::Decoded,
367-
encoded: &mut [u8],
368-
offset: &mut usize,
369-
) -> Result<(), error::EncodeError> {
370-
if decoded.len() != self.0 {
371-
return Err(error::EncodeError::InvalidData);
372-
}
373-
if *offset + self.0 > encoded.len() {
374-
return Err(error::EncodeError::BufferTooSmall);
375-
}
376-
encoded[*offset..*offset + self.0].copy_from_slice(decoded);
377-
*offset += self.0;
378-
Ok(())
379-
}
380-
}
381-
382-
impl FixedMeasurer for FixedU8SliceCodec {
383-
fn measure_fixed(&self) -> usize {
384-
self.0
385-
}
386-
}
387-
388-
impl Measurer for FixedU8SliceCodec {
389-
type Decoded = [u8];
390-
fn measure(&self, decoded: &Self::Decoded) -> Result<usize, error::EncodeError> {
391-
if decoded.len() != self.0 {
392-
return Err(error::EncodeError::InvalidData);
393-
}
394-
Ok(self.measure_fixed())
395-
}
396-
}
397-
398312
/// A codec for the `bool` type.
399313
///
400314
/// # Examples

byten/src/lib.rs

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,26 @@
1010
//! - `derive`: Enables procedural macros for deriving codec implementations for structs and enums.
1111
//!
1212
//! # Built-in Codecs
13-
//! | Codec Type | Default for | Description |
14-
//! |--------------------------------------|-------------|-----------------------------------------------------------------------|
15-
//! | `U8Codec` | `u8` | Codec for `u8` type |
16-
//! | `I8Codec` | `i8` | Codec for `i8` type |
17-
//! | `U8ArrayCodec<N>` | `[u8; N]` | Codec for fixed-size arrays of `u8` of size `N` |
18-
//! | `U8ArrayRefCodec<N>` | `&[u8; N]` | Codec for references to fixed-size arrays of `u8` of size `N` |
19-
//! | `FixedU8SliceCodec(length)` | | Codec for fixed-size slices of `u8` of size `length` |
20-
//! | `BoolCodec` | `bool` | Codec for `bool` type |
21-
//! | `BoxCodec(t_codec)` | `Box<T>` | Codec for `Box<T>` where `t_codec` is the codec for `T` |
22-
//! | `ArrayCodec<.., N>(item_codec)` | | Codec for fixed-size arrays of `Item` of size `N` |
23-
//! | `EndianCodec<T>::le()` | | Codec for primitive types with little-endian byte order |
24-
//! | `EndianCodec<T>::be()` | | Codec for primitive types with big-endian byte order |
25-
//! | `SelfCoded<T>::new()` | | Codec for derived type `T` |
26-
//! | `UTF8Codec(bytes_codec)` | | Codec for `&str` type using the provided bytes codec |
27-
//! | `CStrCodec` | `CStr` | Codec for C-style strings (`CStr` and `&CStr`) |
28-
//! | `OwnedCodec(t_codec)` | | Codec that decodes to owned data by cloning from borrowed data |
29-
//! | `VecCodec(item_codec, length_codec)` | | Codec for `Vec<Item>` using the provided item and length codecs |
30-
//! | `RemainingCodec` | | Codec for all remaining bytes in the input |
31-
//! | `UVarBECodec<T>::new()` | | Codec for unsigned variable-length big-endian integers of type `T` |
32-
//! | `OptionCodec(t_codec)` | `Option<T>` | Codec for `Option<T>` using the provided codec for `T` |
33-
//! | `BytesCodec(length_codec)` | | Codec for byte slices with length prefixed by the provided codec |
13+
//! | Codec Type | Default for | #[byten(...)] | Codes |
14+
//! |-----------------------|-------------|---------------------------------------------------------------------------------------------|
15+
//! | [`U8Codec`] | `u8` | `u8` | `u8` type |
16+
//! | [`I8Codec`] | `i8` | `i8` | `i8` type |
17+
//! | [`U8ArrayCodec`] | `[u8; N]` | `[u8; N]` | fixed-size arrays of `u8` of size `N` |
18+
//! | [`U8ArrayRefCodec`] | `&[u8; N]` | `&[u8; N]` | references to fixed-size arrays of `u8` of size `N` |
19+
//! | [`BoolCodec`] | `bool` | `bool` | `bool` type |
20+
//! | [`BoxCodec`] | `Box<T>` | `Box<T>` or `... box` | `Box<T>` where `t_codec` is the codec for `T` |
21+
//! | [`ArrayCodec`] | | `... $arr` | fixed-size arrays, `[Item; N]` |
22+
//! | [`EndianCodec`] | | `... $be` or `... $le` | primitive types with little/big endian byte orders |
23+
//! | [`SelfCoded`] | | `{SelfCoded::<T>::new()}` | derived type `T` |
24+
//! | [`UTF8Codec`] | | `$utf8` | `&str` type using the provided bytes codec |
25+
//! | [`CStrCodec`] | `CStr` | `CStr` or `&CStr` | C-style strings (`CStr` and `&CStr`) |
26+
//! | [`OwnedCodec`] | | `... $own` | owned data by cloning from borrowed data |
27+
//! | [`VecCodec`] | | `... $vec[len]` | `Vec<Item>` using the provided item and length codecs |
28+
//! | [`RemainingCodec`] | | `..` | all remaining bytes in the input |
29+
//! | [`UVarBECodec`] | | `... $uvarbe` | unsigned variable-length big-endian integers |
30+
//! | [`OptionCodec`] | `Option<T>` | `... $opt` | `Option<T>` using the provided codec for `T` |
31+
//! | [`BytesCodec`] | | `$bytes[len]` | byte slices with length prefixed by the provided codec |
32+
//! | [`PhantomCodec`] | | `= expr` | phantom codec with 0 size, codes the given constant value |
3433
//!
3534
3635
mod array;

byten/src/str.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ use std::ffi::CStr;
77
/// # Examples
88
/// ## Fixed Size UTF-8 String
99
/// ```rust
10-
/// use byten::{UTF8Codec, Encoder, Decoder, Measurer, FixedMeasurer, FixedU8SliceCodec, EncoderToVec as _};
10+
/// use byten::{UTF8Codec, Encoder, Decoder, Measurer, FixedMeasurer, BytesCodec, PhantomCodec, EncoderToVec as _};
1111
///
1212
/// let s: &str = "Hello, world!";
13-
/// let codec = UTF8Codec::new(FixedU8SliceCodec::new(13));
13+
/// let codec = UTF8Codec::new(BytesCodec::new(PhantomCodec::new(13)));
1414
///
1515
/// let encoded = codec.encode_to_vec(s).unwrap();
1616
/// assert_eq!(encoded.len(), 13);
@@ -23,9 +23,6 @@ use std::ffi::CStr;
2323
///
2424
/// let size = codec.measure(s).unwrap();
2525
/// assert_eq!(size, 13);
26-
///
27-
/// let fixed_size = codec.measure_fixed();
28-
/// assert_eq!(fixed_size, 13);
2926
/// ```
3027
///
3128
/// ## Variable Size UTF-8 String with Length Prefix

0 commit comments

Comments
 (0)