1
0
Fork 0
mirror of https://codeberg.org/icewind/bitbuffer.git synced 2026-06-03 16:44:06 +02:00

support reading unnamed structs

This commit is contained in:
Robin Appelman 2019-06-22 17:45:53 +02:00
commit e56f636905
2 changed files with 63 additions and 43 deletions

View file

@ -213,12 +213,8 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
let span = struct_name.span();
match data {
Data::Struct(DataStruct {
fields: Fields::Named(fields),
..
}) => {
let definitions = fields.named.iter().map(|f| {
let name = &f.ident;
Data::Struct(DataStruct { fields, .. }) => {
let values = fields.iter().map(|f| {
// Get attributes `#[..]` on each field
let size = get_field_size(&f.attrs, f.span());
let field_type = &f.ty;
@ -226,19 +222,28 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
match size {
Some(size) => {
quote_spanned! { span =>
let #name:#field_type = {
{
let _size: usize = #size;
stream.read_sized(_size)?
};
stream.read_sized::<#field_type>(_size)?
}
}
}
None => {
quote_spanned! { span =>
let #name:#field_type = stream.read()?;
stream.read::<#field_type>()?
}
}
}
});
match &fields {
Fields::Named(fields) => {
let definitions = fields.named.iter().zip(values).map(|(f, value)| {
let name = &f.ident;
quote_spanned! { f.span() =>
let #name = #value;
}
});
let struct_definition = fields.named.iter().map(|f| {
let name = &f.ident;
quote_spanned! { f.span() =>
@ -253,12 +258,14 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
})
}
}
Data::Struct(DataStruct {
fields: Fields::Unit,
..
}) => {
quote_spanned! {span=>
Fields::Unnamed(_) => quote_spanned! { span =>
Ok(#struct_name(
#(#values ,)*
))
},
Fields::Unit => quote_spanned! {span=>
Ok(#struct_name)
},
}
}
Data::Enum(data) => {
@ -399,13 +406,10 @@ fn derive_bitsize_trait(
// Generate an expression to sum up the heap size of each field.
fn bit_size_sum(data: Data) -> TokenStream {
match data {
Data::Struct(DataStruct {
fields: Fields::Named(fields),
..
}) => {
let recurse = fields.named.into_iter().map(|f| {
Data::Struct(DataStruct { fields, .. }) => {
let recurse = fields.iter().map(|f| {
let span = f.span();
let field_type = f.ty;
let field_type = &f.ty;
match get_field_size(&f.attrs, span) {
Some(size) => {
quote_spanned! {span =>
@ -423,10 +427,6 @@ fn bit_size_sum(data: Data) -> TokenStream {
0 # ( + # recurse) *
}
}
Data::Struct(DataStruct {
fields: Fields::Unit,
..
}) => quote!(0),
_ => unimplemented!(),
}
}

View file

@ -265,6 +265,22 @@ fn test_read_rest_enum() {
assert_eq!(TestEnumRest::Asd, stream.read().unwrap());
}
#[derive(BitRead, PartialEq, Debug)]
struct UnnamedSize(u8, #[size = 5] String, bool);
fn test_unnamed_struct() {
let bytes = vec![
12, 'h' as u8, 'e' as u8, 'l' as u8, 'l' as u8, 'o' as u8, 0, 0, 0, 0, 0, 0,
];
let buffer = BitBuffer::new(bytes, LittleEndian);
let mut stream = BitStream::from(buffer);
assert_eq!(
UnnamedSize(12, "hello".to_string(), false),
stream.read().unwrap()
);
}
#[derive(BitRead, BitSize, PartialEq, Debug)]
struct EmptyStruct;
@ -285,9 +301,13 @@ struct SizeStruct {
bar: bool,
}
#[derive(BitSize)]
struct UnnamedSizeStruct(u8, #[size = 6] String, bool);
#[test]
fn test_bit_size() {
assert_eq!(bit_size_of::<SizeStruct>(), 8 + 8 * 6 + 1);
assert_eq!(bit_size_of::<UnnamedSizeStruct>(), 8 + 8 * 6 + 1);
}
#[derive(BitSizeSized)]