mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 08:34:07 +02:00
derive unchecked methods for traits
This commit is contained in:
parent
55eb866eb6
commit
a6e9b59ece
2 changed files with 39 additions and 13 deletions
|
|
@ -191,7 +191,8 @@ fn derive_bitread_trait(
|
|||
&input.attrs,
|
||||
extra_param.is_some(),
|
||||
);
|
||||
let parse = parse(input.data, &name, &input.attrs);
|
||||
let parsed = parse(input.data.clone(), &name, &input.attrs, false);
|
||||
let parsed_unchecked = parse(input.data.clone(), &name, &input.attrs, true);
|
||||
|
||||
let endianness_placeholder = endianness.unwrap_or("_E".to_owned());
|
||||
let trait_def_str = format!(
|
||||
|
|
@ -216,11 +217,15 @@ fn derive_bitread_trait(
|
|||
},
|
||||
Span::call_site(),
|
||||
);
|
||||
|
||||
//
|
||||
let expanded = quote! {
|
||||
impl #impl_generics #trait_def for #name #ty_generics #where_clause {
|
||||
fn read(stream: &mut ::bitstream_reader::BitStream<#endianness_ident>#extra_param) -> ::bitstream_reader::Result<Self> {
|
||||
#parse
|
||||
#parsed
|
||||
}
|
||||
|
||||
unsafe fn read_unchecked(stream: &mut ::bitstream_reader::BitStream<#endianness_ident>#extra_param) -> ::bitstream_reader::Result<Self> {
|
||||
#parsed_unchecked
|
||||
}
|
||||
|
||||
fn #size_method_name(#size_extra_param) -> Option<usize> {
|
||||
|
|
@ -234,7 +239,7 @@ fn derive_bitread_trait(
|
|||
proc_macro::TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream {
|
||||
fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>, unchecked: bool) -> TokenStream {
|
||||
let span = struct_name.span();
|
||||
|
||||
match data {
|
||||
|
|
@ -244,18 +249,36 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
|
|||
let size = get_field_size(&f.attrs, f.span());
|
||||
let field_type = &f.ty;
|
||||
let span = f.span();
|
||||
match size {
|
||||
Some(size) => {
|
||||
quote_spanned! { span =>
|
||||
{
|
||||
let _size: usize = #size;
|
||||
stream.read_sized::<#field_type>(_size)?
|
||||
if unchecked {
|
||||
match size {
|
||||
Some(size) => {
|
||||
quote_spanned! { span =>
|
||||
{
|
||||
let _size: usize = #size;
|
||||
stream.read_sized_unchecked::<#field_type>(_size)?
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
quote_spanned! { span =>
|
||||
stream.read_unchecked::<#field_type>()?
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
quote_spanned! { span =>
|
||||
stream.read::<#field_type>()?
|
||||
} else {
|
||||
match size {
|
||||
Some(size) => {
|
||||
quote_spanned! { span =>
|
||||
{
|
||||
let _size: usize = #size;
|
||||
stream.read_sized::<#field_type>(_size)?
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
quote_spanned! { span =>
|
||||
stream.read::<#field_type>()?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ pub trait BitRead<E: Endianness>: Sized {
|
|||
/// Read the type from stream
|
||||
fn read(stream: &mut BitStream<E>) -> Result<Self>;
|
||||
|
||||
/// Note: only the bounds are unchecked
|
||||
///
|
||||
/// any other validations (e.g. checking for valid utf8) still needs to be done
|
||||
#[doc(hidden)]
|
||||
unsafe fn read_unchecked(stream: &mut BitStream<E>) -> Result<Self> {
|
||||
Self::read(stream)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue