mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +02:00
use the smallest possible size int for descriminant reading/writing
This commit is contained in:
parent
2a1718b5f6
commit
eb4bafc310
4 changed files with 40 additions and 18 deletions
|
|
@ -144,7 +144,7 @@ use quote::{quote, quote_spanned};
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse_macro_input, parse_quote, parse_str, Attribute, Data, DataStruct, DeriveInput, Expr,
|
parse_macro_input, parse_quote, parse_str, Attribute, Data, DataStruct, DeriveInput, Expr,
|
||||||
Fields, GenericParam, Ident, Lit, LitStr, Path,
|
Fields, GenericParam, Ident, Lit, LitInt, LitStr, Path,
|
||||||
};
|
};
|
||||||
use syn_util::get_attribute_value;
|
use syn_util::get_attribute_value;
|
||||||
|
|
||||||
|
|
@ -414,14 +414,16 @@ fn parse(data: Data, struct_name: &Ident, attrs: &[Attribute], unchecked: bool)
|
||||||
|
|
||||||
let discriminant_token: TokenStream = match Discriminant::from(variant) {
|
let discriminant_token: TokenStream = match Discriminant::from(variant) {
|
||||||
Discriminant::Int(discriminant) => {
|
Discriminant::Int(discriminant) => {
|
||||||
|
let lit = LitInt::new(&format!("{}", discriminant), span);
|
||||||
last_discriminant = discriminant as isize;
|
last_discriminant = discriminant as isize;
|
||||||
quote_spanned! { span => #discriminant }
|
quote_spanned! { span => #lit }
|
||||||
}
|
}
|
||||||
Discriminant::Wildcard => quote_spanned! { span => _ },
|
Discriminant::Wildcard => quote_spanned! { span => _ },
|
||||||
Discriminant::Default => {
|
Discriminant::Default => {
|
||||||
let new_discriminant = (last_discriminant + 1) as usize;
|
let new_discriminant = (last_discriminant + 1) as usize;
|
||||||
|
let lit = LitInt::new(&format!("{}", new_discriminant), span);
|
||||||
last_discriminant += 1;
|
last_discriminant += 1;
|
||||||
quote_spanned! { span => #new_discriminant }
|
quote_spanned! { span => #lit }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
|
|
@ -431,13 +433,15 @@ fn parse(data: Data, struct_name: &Ident, attrs: &[Attribute], unchecked: bool)
|
||||||
|
|
||||||
let span = data.enum_token.span();
|
let span = data.enum_token.span();
|
||||||
|
|
||||||
|
let repr = repr_for_bits(discriminant_bits);
|
||||||
|
|
||||||
let enum_name = Lit::Str(LitStr::new(&struct_name.to_string(), struct_name.span()));
|
let enum_name = Lit::Str(LitStr::new(&struct_name.to_string(), struct_name.span()));
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
let discriminant:usize = stream.read_int(#discriminant_bits as usize)?;
|
let discriminant:#repr = stream.read_int(#discriminant_bits as usize)?;
|
||||||
Ok(match discriminant {
|
Ok(match discriminant {
|
||||||
#(#match_arms)*
|
#(#match_arms)*
|
||||||
_ => {
|
_ => {
|
||||||
return Err(::bitbuffer::BitError::UnmatchedDiscriminant{discriminant, enum_name: #enum_name.to_string()})
|
return Err(::bitbuffer::BitError::UnmatchedDiscriminant{discriminant: discriminant as usize, enum_name: #enum_name.to_string()})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -555,3 +559,15 @@ fn get_field_size(attrs: &[Attribute], span: Span) -> Option<TokenStream> {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn repr_for_bits(discriminant_bits: u64) -> TokenStream {
|
||||||
|
if discriminant_bits <= 8 {
|
||||||
|
quote!(u8)
|
||||||
|
} else if discriminant_bits <= 16 {
|
||||||
|
quote!(u16)
|
||||||
|
} else if discriminant_bits <= 32 {
|
||||||
|
quote!(u32)
|
||||||
|
} else {
|
||||||
|
quote!(usize)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
use crate::discriminant::Discriminant;
|
use crate::discriminant::Discriminant;
|
||||||
use crate::size;
|
use crate::{repr_for_bits, size};
|
||||||
use proc_macro2::{Span, TokenStream};
|
use proc_macro2::{Span, TokenStream};
|
||||||
use quote::{quote, quote_spanned};
|
use quote::{quote, quote_spanned};
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
parse_macro_input, parse_quote, parse_str, Attribute, Data, DataStruct, DeriveInput, Expr,
|
parse_macro_input, parse_quote, parse_str, Attribute, Data, DataStruct, DeriveInput, Expr,
|
||||||
Fields, GenericParam, Ident, Index, Lit, Member, Path, Type,
|
Fields, GenericParam, Ident, Index, Lit, LitInt, Member, Path, Type,
|
||||||
};
|
};
|
||||||
use syn_util::get_attribute_value;
|
use syn_util::get_attribute_value;
|
||||||
|
|
||||||
|
|
@ -182,17 +182,20 @@ fn write(data: Data, struct_name: &Ident, attrs: &[Attribute]) -> TokenStream {
|
||||||
|
|
||||||
let discriminant_token: TokenStream = match Discriminant::from(variant) {
|
let discriminant_token: TokenStream = match Discriminant::from(variant) {
|
||||||
Discriminant::Int(discriminant) => {
|
Discriminant::Int(discriminant) => {
|
||||||
|
let lit = LitInt::new(&format!("{}", discriminant), span);
|
||||||
last_discriminant = discriminant as isize;
|
last_discriminant = discriminant as isize;
|
||||||
quote_spanned! { span => #discriminant }
|
quote_spanned! { span => #lit }
|
||||||
}
|
}
|
||||||
Discriminant::Wildcard => {
|
Discriminant::Wildcard => {
|
||||||
let free_discriminant = max_discriminant + 1;
|
let free_discriminant = max_discriminant + 1;
|
||||||
quote_spanned! { span => #free_discriminant }
|
let lit = LitInt::new(&format!("{}", free_discriminant), span);
|
||||||
|
quote_spanned! { span => #lit }
|
||||||
}
|
}
|
||||||
Discriminant::Default => {
|
Discriminant::Default => {
|
||||||
let new_discriminant = (last_discriminant + 1) as usize;
|
let new_discriminant = (last_discriminant + 1) as usize;
|
||||||
|
let lit = LitInt::new(&format!("{}", new_discriminant), span);
|
||||||
last_discriminant += 1;
|
last_discriminant += 1;
|
||||||
quote_spanned! { span => #new_discriminant }
|
quote_spanned! { span => #lit }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -240,12 +243,13 @@ fn write(data: Data, struct_name: &Ident, attrs: &[Attribute]) -> TokenStream {
|
||||||
});
|
});
|
||||||
|
|
||||||
let span = data.enum_token.span();
|
let span = data.enum_token.span();
|
||||||
|
let repr = repr_for_bits(discriminant_bits);
|
||||||
|
|
||||||
quote_spanned! {span=>
|
quote_spanned! {span=>
|
||||||
let discriminant = match &self {
|
let discriminant:#repr = match &self {
|
||||||
#(#discriminant_value),*
|
#(#discriminant_value),*
|
||||||
};
|
};
|
||||||
__target__stream.write_int(discriminant as usize, #discriminant_bits as usize)?;
|
__target__stream.write_int(discriminant, #discriminant_bits as usize)?;
|
||||||
match &self {
|
match &self {
|
||||||
#(#write_inner)*
|
#(#write_inner)*
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,13 @@
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
use bitbuffer::{BitReadStream, Endianness};
|
use bitbuffer::{BitReadStream, Endianness};
|
||||||
use bitbuffer_derive::{BitWrite, BitWriteSized};
|
use bitbuffer_derive::{BitRead, BitWrite, BitWriteSized};
|
||||||
|
|
||||||
#[derive(BitWrite)]
|
#[derive(BitWrite)]
|
||||||
struct TestSizeExpression {
|
#[discriminant_bits = 4]
|
||||||
size: u8,
|
enum TestEnumRest {
|
||||||
#[size = "size + 2"]
|
Foo,
|
||||||
str: String,
|
Bar,
|
||||||
|
#[discriminant = "_"]
|
||||||
|
Asd,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,7 @@ where
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_bit_size < USIZE_BITS {
|
if type_bit_size < USIZE_BITS || count < USIZE_BITS {
|
||||||
self.push_bits(value.into_usize_unchecked(), count);
|
self.push_bits(value.into_usize_unchecked(), count);
|
||||||
} else {
|
} else {
|
||||||
self.push_non_fit_bits(value.into_bytes(), count)
|
self.push_non_fit_bits(value.into_bytes(), count)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue