Open T-Bakker opened 2 years ago
Hi,
Unfortunately, type aliases are not supported in this way. A derive macro in Rust receives only the source of the particular struct, with no way to inspect the previously defined alias. It might be possible to support this exact scenario by implementing the packing traits on the Integer<>
wrappers, but for now, this isn't supported. The definitions would also need to be even more explicit, as there is also a semi-hidden MSB/LSB wrapper around them.
However, if you want, you can define a structure just for this case, but then you need to give a hint what is the exact width of each individual field. A Deref
implementation on the helper struct will also help with the ergonomics. I've written a small test and this seems to work fine for me. Not sure what you meant by byte boundary, but structures can be placed on a per bit level.
use packed_struct::prelude::*;
#[derive(PackedStruct, Debug, Clone, Copy, PartialEq, Default)]
#[packed_struct(bit_numbering="msb0")]
pub struct FieldStruct {
#[packed_field(bits="4..")]
pub data: Integer<u8, packed_bits::Bits::<4>>
}
#[derive(PackedStruct, Debug, Clone, Copy, PartialEq, Default)]
#[packed_struct(bit_numbering="msb0")]
pub struct S {
#[packed_field(bits="0..4")]
pub a: FieldStruct,
#[packed_field(size_bits="4")]
pub b: FieldStruct
}
#[test]
#[cfg(test)]
fn test_packed_type_alias() {
let mut s = S::default();
s.a.data = 0b1001.into();
s.b.data = 0b0110.into();
println!("data: {:#?}", s);
let packed = s.pack().unwrap();
println!("packed: {:#X?}", packed);
let u = S::unpack(&packed).unwrap();
assert_eq!(s, u);
}
This actually compiles:
pub type Field = MsbInteger<u8, packed_bits::Bits::<4>, Integer<u8, packed_bits::Bits::<4>>>;
#[derive(PackedStruct)]
#[packed_struct(bit_numbering="msb0")]
pub struct S {
#[packed_field(bits="0..", size_bits="4")]
pub a: Field,
#[packed_field(size_bits="4")]
pub b: Field
}
However those types were never designed to be used this way, so there are a couple of conversion traits that would have to be implemented to make things usable. Also, it's missing the critical traits like Copy/Clone/PartialEq/etc... So a valid feature request, but I'd have to dig a bit deeper how this interacts with the generated code.
Would appreciate this implementation, i have a downstream upstream (code flow) of packed types and I rather they pass in the proper type size than cross my fingers im not truncating types
Hi,
I am trying to replace
modular_bitfield
withpacket_struct
as that library is no longer maintained. As such, I am trying to usepacket_struct
with a non-struct type as a field:This results in the following error: Couldn't determine the bit/byte width for this field.
Please note that I use the
Field
type in various structs in my code. Removing that type and simply specifyingInterger<...>
for each usage is undesired. I can also not use struct nesting as the struct require a byte boundary, which is not possible for me.Explicitly specifying the bit positions results in a different error which I do not fully understand:
Error: no function or associated item named
unpack
found for structpacked_struct::types::Integer<u8, Bits<4_usize>>
in the current scope function or associated item not found in `packed_struct::types::Integer<u8, Bits<4_usize>>Am I missing something? Is this possible somehow?
Thanks in advance, Tommas