Skip to content

Commit 0994bd7

Browse files
authored
Merge pull request #69 from hashmismatch/const_generics
Const generics for byte array types
2 parents 5e331f6 + 973104b commit 0994bd7

28 files changed

+297
-280
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ provide safe packing, unpacking and runtime debugging formatters with per-field
3535

3636
```toml
3737
[dependencies]
38-
packed_struct = "0.6"
38+
packed_struct = "0.10"
3939
```
4040
## Importing the library with the the most common traits and the derive macros
4141

@@ -55,7 +55,7 @@ use packed_struct::prelude::*;
5555
#[packed_struct(bit_numbering="msb0")]
5656
pub struct TestPack {
5757
#[packed_field(bits="0..=2")]
58-
tiny_int: Integer<u8, packed_bits::Bits3>,
58+
tiny_int: Integer<u8, packed_bits::Bits::<3>>,
5959
#[packed_field(bits="3..=4", ty="enum")]
6060
mode: SelfTestMode,
6161
#[packed_field(bits="7")]
@@ -176,7 +176,7 @@ use packed_struct::prelude::*;
176176
#[derive(PackedStruct)]
177177
#[packed_struct(endian="lsb")]
178178
pub struct LsbIntExample {
179-
int1: Integer<u32, packed_bits::Bits24>,
179+
int1: Integer<u32, packed_bits::Bits::<24>>,
180180
}
181181

182182
fn main() -> Result<(), PackingError> {
@@ -229,9 +229,9 @@ use packed_struct::prelude::*;
229229
#[derive(PackedStruct, Default, Debug, PartialEq)]
230230
#[packed_struct(bit_numbering="msb0")]
231231
pub struct TinyFlags {
232-
_reserved: ReservedZero<packed_bits::Bits4>,
232+
_reserved: ReservedZero<packed_bits::Bits::<4>>,
233233
flag1: bool,
234-
val1: Integer<u8, packed_bits::Bits2>,
234+
val1: Integer<u8, packed_bits::Bits::<2>>,
235235
flag2: bool
236236
}
237237

packed_struct/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@ name = "packed_struct"
33
description = "Binary-level structure packing and unpacking generator"
44
repository = "https://github.com/hashmismatch/packed_struct.rs"
55
homepage = "http://www.hashmismatch.net/libraries/packed-struct/"
6-
version = "0.6.1"
6+
version = "0.10.0"
7+
rust-version = "1.51"
78
authors = ["Rudi Benkovic <[email protected]>"]
8-
build = "build.rs"
99
license = "MIT OR Apache-2.0"
1010
keywords = ["enum", "packing", "serialization"]
1111
categories = ["encoding"]
1212
readme = "../README.md"
1313
edition = "2018"
1414

1515
[dependencies]
16-
packed_struct_codegen = { path = "../packed_struct_codegen/", version = "0.6.1" }
16+
packed_struct_codegen = { path = "../packed_struct_codegen/", version = "0.10.0" }
1717
serde = { version = "1.0", optional = true, default-features = false }
1818
serde_derive = { version = "1.0", optional = true }
19+
bitvec = { version = "0.22.3", default-features = false }
1920

2021
[features]
2122
default = ["std"]

packed_struct/build.rs

+1-8
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,9 @@ fn main() {
2121
32
2222
};
2323

24-
// bytes
25-
for i in 0..(up_to_bytes + 1) {
26-
27-
let b = format!("bytes_type!(Bytes{}, {});\r\n", i, i);
28-
f.write_all(b.as_bytes()).unwrap();
29-
}
30-
3124
// bits
3225
for i in 1..(up_to_bytes * 8) {
33-
let b = format!("bits_type!(Bits{}, {}, Bytes{}, {});\r\n", i, i, (i as f32 / 8.0).ceil() as usize, if (i % 8) == 0 {
26+
let b = format!("bits_type!(Bits::<{}>, {}, Bytes::<{}>, {});\r\n", i, i, (i as f32 / 8.0).ceil() as usize, if (i % 8) == 0 {
3427
"BitsFullBytes"
3528
} else {
3629
"BitsPartialBytes"

packed_struct/src/lib.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
//!
3636
//! ```toml
3737
//! [dependencies]
38-
//! packed_struct = "0.6"
38+
//! packed_struct = "0.10"
3939
//! ```
4040
//! ## Importing the library with the the most common traits and the derive macros
4141
//!
@@ -57,7 +57,7 @@
5757
//! #[packed_struct(bit_numbering="msb0")]
5858
//! pub struct TestPack {
5959
//! #[packed_field(bits="0..=2")]
60-
//! tiny_int: Integer<u8, packed_bits::Bits3>,
60+
//! tiny_int: Integer<u8, packed_bits::Bits::<3>>,
6161
//! #[packed_field(bits="3..=4", ty="enum")]
6262
//! mode: SelfTestMode,
6363
//! #[packed_field(bits="7")]
@@ -180,7 +180,7 @@
180180
//! #[derive(PackedStruct)]
181181
//! #[packed_struct(endian="lsb")]
182182
//! pub struct LsbIntExample {
183-
//! int1: Integer<u32, packed_bits::Bits24>,
183+
//! int1: Integer<u32, packed_bits::Bits::<24>>,
184184
//! }
185185
//!
186186
//! fn main() -> Result<(), PackingError> {
@@ -233,9 +233,9 @@
233233
//! #[derive(PackedStruct, Default, Debug, PartialEq)]
234234
//! #[packed_struct(bit_numbering="msb0")]
235235
//! pub struct TinyFlags {
236-
//! _reserved: ReservedZero<packed_bits::Bits4>,
236+
//! _reserved: ReservedZero<packed_bits::Bits::<4>>,
237237
//! flag1: bool,
238-
//! val1: Integer<u8, packed_bits::Bits2>,
238+
//! val1: Integer<u8, packed_bits::Bits::<2>>,
239239
//! flag2: bool
240240
//! }
241241
//!

packed_struct/src/packing.rs

+2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use crate::types_bits::ByteArray;
1010
///
1111
/// 10 bits packs into: [0b00000011, 0b11111111]
1212
pub trait PackedStruct where Self: Sized {
13+
/// The appropriately sized byte array into which this structure will be packed, for example [u8; 2].
1314
type ByteArray : ByteArray;
15+
1416
/// Packs the structure into a byte array.
1517
fn pack(&self) -> PackingResult<Self::ByteArray>;
1618
/// Unpacks the structure from a byte array.

packed_struct/src/types_array.rs

+18-56
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,23 @@
1-
use super::packing::*;
1+
use crate::{PackedStruct, PackedStructInfo, PackingError, PackingResult};
22

3-
macro_rules! packable_u8_array {
4-
($N: expr) => (
3+
impl<const N: usize> PackedStruct for [u8; N] {
4+
type ByteArray = [u8; N];
55

6-
impl PackedStruct for [u8; $N] {
7-
type ByteArray = [u8; $N];
6+
#[inline]
7+
fn pack(&self) -> PackingResult<Self::ByteArray> {
8+
Ok(*self)
9+
}
810

9-
#[inline]
10-
fn pack(&self) -> PackingResult<Self::ByteArray> {
11-
Ok(*self)
12-
}
13-
14-
#[inline]
15-
fn unpack(src: &Self::ByteArray) -> Result<Self::ByteArray, PackingError> {
16-
Ok(*src)
17-
}
18-
}
19-
20-
impl PackedStructInfo for [u8; $N] {
21-
#[inline]
22-
fn packed_bits() -> usize {
23-
$N * 8
24-
}
25-
}
26-
)
11+
#[inline]
12+
fn unpack(src: &Self::ByteArray) -> Result<Self::ByteArray, PackingError> {
13+
Ok(*src)
14+
}
2715
}
2816

29-
packable_u8_array!(0);
30-
packable_u8_array!(1);
31-
packable_u8_array!(2);
32-
packable_u8_array!(3);
33-
packable_u8_array!(4);
34-
packable_u8_array!(5);
35-
packable_u8_array!(6);
36-
packable_u8_array!(7);
37-
packable_u8_array!(8);
38-
packable_u8_array!(9);
39-
packable_u8_array!(10);
40-
packable_u8_array!(11);
41-
packable_u8_array!(12);
42-
packable_u8_array!(13);
43-
packable_u8_array!(14);
44-
packable_u8_array!(15);
45-
packable_u8_array!(16);
46-
packable_u8_array!(17);
47-
packable_u8_array!(18);
48-
packable_u8_array!(19);
49-
packable_u8_array!(20);
50-
packable_u8_array!(21);
51-
packable_u8_array!(22);
52-
packable_u8_array!(23);
53-
packable_u8_array!(24);
54-
packable_u8_array!(25);
55-
packable_u8_array!(26);
56-
packable_u8_array!(27);
57-
packable_u8_array!(28);
58-
packable_u8_array!(29);
59-
packable_u8_array!(30);
60-
packable_u8_array!(31);
61-
packable_u8_array!(32);
17+
18+
impl<const N: usize> PackedStructInfo for [u8; N] {
19+
#[inline]
20+
fn packed_bits() -> usize {
21+
N * 8
22+
}
23+
}

packed_struct/src/types_bits.rs

+37-37
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ pub trait NumberOfBits: Copy + Clone + Debug + Default {
1010

1111
/// The numerical number of bits.
1212
fn number_of_bits() -> usize;
13+
14+
fn byte_array_len() -> usize {
15+
<<Self::Bytes as NumberOfBytes>::AsBytes as ByteArray>::len()
16+
}
1317
}
1418

1519
/// These bits are a multiple of 8
@@ -30,61 +34,57 @@ pub trait NumberOfBytes: Copy + Clone + Debug + Default {
3034
}
3135

3236
/// Helper that allows us to cast a fixed size array into a byte slice.
33-
pub trait ByteArray {
37+
pub trait ByteArray: Clone {
3438
fn len() -> usize;
3539
fn as_bytes_slice(&self) -> &[u8];
3640
fn as_mut_bytes_slice(&mut self) -> &mut [u8];
3741
fn rotate_right(&mut self, bytes: usize);
3842
fn new(value: u8) -> Self;
3943
}
4044

41-
macro_rules! bytes_type {
42-
($T: ident, $N: expr) => {
43-
#[derive(Copy, Clone, Debug, Default, PartialEq)]
44-
pub struct $T;
45+
impl<const N: usize> ByteArray for [u8; N] {
46+
#[inline]
47+
fn len() -> usize {
48+
N
49+
}
4550

46-
impl NumberOfBytes for $T {
47-
type AsBytes = [u8; $N];
51+
#[inline]
52+
fn as_bytes_slice(&self) -> &[u8] {
53+
&self[..]
54+
}
4855

49-
#[inline]
50-
fn number_of_bytes() -> usize {
51-
$N
52-
}
53-
}
56+
#[inline]
57+
fn as_mut_bytes_slice(&mut self) -> &mut [u8] {
58+
&mut self[..]
59+
}
5460

55-
impl ByteArray for [u8; $N] {
56-
#[inline]
57-
fn len() -> usize {
58-
$N
59-
}
61+
#[inline]
62+
fn rotate_right(&mut self, bytes: usize) {
63+
bytes_rotate_right(self, bytes)
64+
}
6065

61-
#[inline]
62-
fn as_bytes_slice(&self) -> &[u8] {
63-
&self[..]
64-
}
66+
fn new(value: u8) -> Self {
67+
[value; N]
68+
}
69+
}
6570

66-
#[inline]
67-
fn as_mut_bytes_slice(&mut self) -> &mut [u8] {
68-
&mut self[..]
69-
}
71+
#[derive(Default, Debug, Copy, Clone, PartialEq)]
72+
pub struct Bytes<const N: usize>;
7073

71-
#[inline]
72-
fn rotate_right(&mut self, bytes: usize) {
73-
bytes_rotate_right(self, bytes)
74-
}
74+
impl<const N: usize> NumberOfBytes for Bytes<N> {
75+
type AsBytes = [u8; N];
7576

76-
fn new(value: u8) -> Self {
77-
[value; $N]
78-
}
79-
}
77+
#[inline]
78+
fn number_of_bytes() -> usize {
79+
N
8080
}
8181
}
8282

83-
macro_rules! bits_type {
84-
($T: ident, $N: expr, $TB: ident, $TBK: ident) => {
85-
#[derive(Copy, Clone, Debug, Default, PartialEq)]
86-
pub struct $T;
83+
#[derive(Default, Debug, Copy, Clone, PartialEq)]
84+
pub struct Bits<const N: usize>;
8785

86+
macro_rules! bits_type {
87+
($T: ty, $N: expr, $TB: ty, $TBK: ident) => {
8888
impl NumberOfBits for $T {
8989
type Bytes = $TB;
9090

0 commit comments

Comments
 (0)