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:
parent
896dff8367
commit
e56f636905
2 changed files with 63 additions and 43 deletions
|
|
@ -213,39 +213,44 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
|
||||||
let span = struct_name.span();
|
let span = struct_name.span();
|
||||||
|
|
||||||
match data {
|
match data {
|
||||||
Data::Struct(DataStruct {
|
Data::Struct(DataStruct { fields, .. }) => {
|
||||||
fields: Fields::Named(fields),
|
let values = fields.iter().map(|f| {
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
let definitions = fields.named.iter().map(|f| {
|
|
||||||
let name = &f.ident;
|
|
||||||
// Get attributes `#[..]` on each field
|
// Get attributes `#[..]` on each field
|
||||||
let size = get_field_size(&f.attrs, f.span());
|
let size = get_field_size(&f.attrs, f.span());
|
||||||
let field_type = &f.ty;
|
let field_type = &f.ty;
|
||||||
let span = f.span();
|
let span = f.span();
|
||||||
match size {
|
match size {
|
||||||
Some(size) => {
|
Some(size) => {
|
||||||
quote_spanned! {span=>
|
quote_spanned! { span =>
|
||||||
let #name:#field_type = {
|
{
|
||||||
let _size: usize = #size;
|
let _size: usize = #size;
|
||||||
stream.read_sized(_size)?
|
stream.read_sized::<#field_type>(_size)?
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
quote_spanned! {span=>
|
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 struct_definition = fields.named.iter().map(|f| {
|
||||||
let name = &f.ident;
|
let name = &f.ident;
|
||||||
quote_spanned! {f.span()=>
|
quote_spanned! { f.span() =>
|
||||||
#name,
|
#name,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
quote_spanned! {span=>
|
quote_spanned! { span =>
|
||||||
#(#definitions)*
|
#(#definitions)*
|
||||||
|
|
||||||
Ok(#struct_name {
|
Ok(#struct_name {
|
||||||
|
|
@ -253,12 +258,14 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Data::Struct(DataStruct {
|
Fields::Unnamed(_) => quote_spanned! { span =>
|
||||||
fields: Fields::Unit,
|
Ok(#struct_name(
|
||||||
..
|
#(#values ,)*
|
||||||
}) => {
|
))
|
||||||
quote_spanned! {span=>
|
},
|
||||||
|
Fields::Unit => quote_spanned! {span=>
|
||||||
Ok(#struct_name)
|
Ok(#struct_name)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Data::Enum(data) => {
|
Data::Enum(data) => {
|
||||||
|
|
@ -278,7 +285,7 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
|
||||||
let size = get_field_size(&variant.attrs, f.span());
|
let size = get_field_size(&variant.attrs, f.span());
|
||||||
match size {
|
match size {
|
||||||
Some(size) => {
|
Some(size) => {
|
||||||
quote_spanned! {span=>
|
quote_spanned! { span =>
|
||||||
#struct_name::#variant_name({
|
#struct_name::#variant_name({
|
||||||
let _size:usize = #size;
|
let _size:usize = #size;
|
||||||
stream.read_sized(_size)?
|
stream.read_sized(_size)?
|
||||||
|
|
@ -286,7 +293,7 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
quote_spanned! {span=>
|
quote_spanned! { span =>
|
||||||
#struct_name::#variant_name(stream.read()?)
|
#struct_name::#variant_name(stream.read()?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -399,13 +406,10 @@ fn derive_bitsize_trait(
|
||||||
// Generate an expression to sum up the heap size of each field.
|
// Generate an expression to sum up the heap size of each field.
|
||||||
fn bit_size_sum(data: Data) -> TokenStream {
|
fn bit_size_sum(data: Data) -> TokenStream {
|
||||||
match data {
|
match data {
|
||||||
Data::Struct(DataStruct {
|
Data::Struct(DataStruct { fields, .. }) => {
|
||||||
fields: Fields::Named(fields),
|
let recurse = fields.iter().map(|f| {
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
let recurse = fields.named.into_iter().map(|f| {
|
|
||||||
let span = f.span();
|
let span = f.span();
|
||||||
let field_type = f.ty;
|
let field_type = &f.ty;
|
||||||
match get_field_size(&f.attrs, span) {
|
match get_field_size(&f.attrs, span) {
|
||||||
Some(size) => {
|
Some(size) => {
|
||||||
quote_spanned! {span =>
|
quote_spanned! {span =>
|
||||||
|
|
@ -423,10 +427,6 @@ fn bit_size_sum(data: Data) -> TokenStream {
|
||||||
0 # ( + # recurse) *
|
0 # ( + # recurse) *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Data::Struct(DataStruct {
|
|
||||||
fields: Fields::Unit,
|
|
||||||
..
|
|
||||||
}) => quote!(0),
|
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -265,6 +265,22 @@ fn test_read_rest_enum() {
|
||||||
assert_eq!(TestEnumRest::Asd, stream.read().unwrap());
|
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)]
|
#[derive(BitRead, BitSize, PartialEq, Debug)]
|
||||||
struct EmptyStruct;
|
struct EmptyStruct;
|
||||||
|
|
||||||
|
|
@ -285,9 +301,13 @@ struct SizeStruct {
|
||||||
bar: bool,
|
bar: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(BitSize)]
|
||||||
|
struct UnnamedSizeStruct(u8, #[size = 6] String, bool);
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_bit_size() {
|
fn test_bit_size() {
|
||||||
assert_eq!(bit_size_of::<SizeStruct>(), 8 + 8 * 6 + 1);
|
assert_eq!(bit_size_of::<SizeStruct>(), 8 + 8 * 6 + 1);
|
||||||
|
assert_eq!(bit_size_of::<UnnamedSizeStruct>(), 8 + 8 * 6 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(BitSizeSized)]
|
#[derive(BitSizeSized)]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue