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

derive unchecked methods for traits

This commit is contained in:
Robin Appelman 2020-01-07 22:36:37 +01:00
commit a6e9b59ece
2 changed files with 39 additions and 13 deletions

View file

@ -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,6 +249,23 @@ 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();
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>()?
}
}
}
} else {
match size {
Some(size) => {
quote_spanned! { span =>
@ -259,6 +281,7 @@ fn parse(data: Data, struct_name: &Ident, attrs: &Vec<Attribute>) -> TokenStream
}
}
}
}
});
match &fields {

View file

@ -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)