mirror of
https://codeberg.org/icewind/bitbuffer.git
synced 2026-06-03 16:44:06 +02:00
borrow data
This commit is contained in:
parent
a276e5a457
commit
0c8d2ebe18
9 changed files with 195 additions and 167 deletions
|
|
@ -112,10 +112,10 @@
|
|||
//! #
|
||||
//! #[derive(BitRead)]
|
||||
//! #[endianness = "E"]
|
||||
//! struct EndiannessStruct<E: Endianness> {
|
||||
//! struct EndiannessStruct<'a, E: Endianness> {
|
||||
//! size: u8,
|
||||
//! #[size = "size"]
|
||||
//! stream: BitReadStream<E>,
|
||||
//! stream: BitReadStream<'a, E>,
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
|
|
@ -125,10 +125,10 @@
|
|||
//! #
|
||||
//! #[derive(BitRead)]
|
||||
//! #[endianness = "BigEndian"]
|
||||
//! struct EndiannessStruct {
|
||||
//! struct EndiannessStruct<'a> {
|
||||
//! size: u8,
|
||||
//! #[size = "size"]
|
||||
//! stream: BitReadStream<BigEndian>,
|
||||
//! stream: BitReadStream<'a, BigEndian>,
|
||||
//! }
|
||||
//! ```
|
||||
extern crate proc_macro;
|
||||
|
|
@ -138,7 +138,7 @@ use quote::{quote, quote_spanned};
|
|||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parse_macro_input, parse_quote, parse_str, Attribute, Data, DataStruct, DeriveInput, Expr,
|
||||
Fields, Ident, Lit, LitStr, Path, Variant,
|
||||
Fields, GenericParam, Ident, Lit, LitStr, Path, Variant,
|
||||
};
|
||||
use syn_util::get_attribute_value;
|
||||
|
||||
|
|
@ -175,6 +175,18 @@ fn derive_bitread_trait(
|
|||
let mut trait_generics = input.generics.clone();
|
||||
// we need these separate generics to only add out Endianness param to the 'impl'
|
||||
let (_, ty_generics, where_clause) = input.generics.split_for_impl();
|
||||
let lifetime: Option<&GenericParam> = trait_generics
|
||||
.params
|
||||
.iter()
|
||||
.filter(|param| matches!(param, GenericParam::Lifetime(_)))
|
||||
.next();
|
||||
let lifetime = match lifetime {
|
||||
Some(GenericParam::Lifetime(lifetime)) => lifetime.lifetime.clone(),
|
||||
_ => {
|
||||
trait_generics.params.push(parse_quote!('a));
|
||||
parse_quote!('a)
|
||||
}
|
||||
};
|
||||
if endianness.is_none() {
|
||||
trait_generics
|
||||
.params
|
||||
|
|
@ -193,7 +205,10 @@ fn derive_bitread_trait(
|
|||
let parsed_unchecked = parse(input.data.clone(), &name, &input.attrs, true);
|
||||
|
||||
let endianness_placeholder = endianness.unwrap_or_else(|| "_E".to_owned());
|
||||
let trait_def_str = format!("::bitbuffer::{}<{}>", trait_name, &endianness_placeholder);
|
||||
let trait_def_str = format!(
|
||||
"::bitbuffer::{}<{}, {}>",
|
||||
trait_name, lifetime, &endianness_placeholder
|
||||
);
|
||||
let trait_def = parse_str::<Path>(&trait_def_str).unwrap();
|
||||
|
||||
let endianness_ident = Ident::new(&endianness_placeholder, span);
|
||||
|
|
@ -218,10 +233,10 @@ 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 ::bitbuffer::BitReadStream<#endianness_ident>#extra_param) -> ::bitbuffer::Result<Self> {
|
||||
fn read(stream: &mut ::bitbuffer::BitReadStream<#lifetime, #endianness_ident>#extra_param) -> ::bitbuffer::Result<Self> {
|
||||
// if the read has a predicable size, we can do the bounds check in one go
|
||||
match <Self as #trait_def>::#size_method_name(#extra_param_call) {
|
||||
Some(size) => {
|
||||
|
|
@ -236,7 +251,7 @@ fn derive_bitread_trait(
|
|||
}
|
||||
}
|
||||
|
||||
unsafe fn read_unchecked(stream: &mut ::bitbuffer::BitReadStream<#endianness_ident>#extra_param, end: bool) -> ::bitbuffer::Result<Self> {
|
||||
unsafe fn read_unchecked(stream: &mut ::bitbuffer::BitReadStream<#lifetime, #endianness_ident>#extra_param, end: bool) -> ::bitbuffer::Result<Self> {
|
||||
#parsed_unchecked
|
||||
}
|
||||
|
||||
|
|
@ -410,12 +425,12 @@ fn size(data: Data, struct_name: &Ident, attrs: &[Attribute], has_input_size: bo
|
|||
match size {
|
||||
Some(size) => {
|
||||
quote_spanned! { span =>
|
||||
<#field_type as ::bitbuffer::BitReadSized<::bitbuffer::LittleEndian>>::bit_size_sized(#size)
|
||||
<#field_type as ::bitbuffer::BitReadSized<'_, ::bitbuffer::LittleEndian>>::bit_size_sized(#size)
|
||||
}
|
||||
}
|
||||
None => {
|
||||
quote_spanned! { span =>
|
||||
<#field_type as ::bitbuffer::BitRead<::bitbuffer::LittleEndian>>::bit_size()
|
||||
<#field_type as ::bitbuffer::BitRead<'_, ::bitbuffer::LittleEndian>>::bit_size()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
bitbuffer_derive/tests/expand.rs
Normal file
10
bitbuffer_derive/tests/expand.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(unreachable_patterns)]
|
||||
|
||||
use bitbuffer_derive::BitRead;
|
||||
|
||||
#[derive(BitRead)]
|
||||
struct TestStruct {
|
||||
foo: u8,
|
||||
str: String,
|
||||
}
|
||||
|
|
@ -45,7 +45,7 @@ fn test_read_struct() {
|
|||
0b0101_0101,
|
||||
0b1010_1010,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStruct {
|
||||
|
|
@ -83,7 +83,7 @@ fn test_read_bare_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(TestBareEnum::Asd, stream.read().unwrap());
|
||||
assert_eq!(TestBareEnum::Foo, stream.read().unwrap());
|
||||
|
|
@ -114,7 +114,7 @@ fn test_read_unnamed_field_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestUnnamedFieldEnum::Asd(0b_00_0110_10),
|
||||
|
|
@ -144,7 +144,7 @@ fn test_read_struct_sized() {
|
|||
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 = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStructSized {
|
||||
|
|
@ -180,7 +180,7 @@ fn test_read_unnamed_field_enum_sized() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestUnnamedFieldEnumSized::Asd(0b_00_0110),
|
||||
|
|
@ -213,7 +213,7 @@ fn test_read_struct2() {
|
|||
'l' as u8,
|
||||
'e' as u8,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(
|
||||
TestStruct2 {
|
||||
|
|
@ -227,16 +227,16 @@ fn test_read_struct2() {
|
|||
|
||||
#[derive(BitRead)]
|
||||
#[endianness = "E"]
|
||||
struct TestStruct3<E: Endianness> {
|
||||
struct TestStruct3<'a, E: Endianness> {
|
||||
size: u8,
|
||||
#[size = "size"]
|
||||
stream: BitReadStream<E>,
|
||||
stream: BitReadStream<'a, E>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_struct3() {
|
||||
let bytes = vec![0b0000_0101, 0, 0, 0, 0, 0, 0, 0];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
let result: TestStruct3<BigEndian> = stream.read().unwrap();
|
||||
assert_eq!(5, result.size);
|
||||
|
|
@ -265,7 +265,7 @@ fn test_read_rest_enum() {
|
|||
0b1000_0100,
|
||||
0b1000_0100,
|
||||
];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(TestEnumRest::Asd, stream.read().unwrap());
|
||||
assert_eq!(TestEnumRest::Foo, stream.read().unwrap());
|
||||
|
|
@ -281,7 +281,7 @@ 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 = BitReadBuffer::new(bytes, LittleEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, LittleEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
|
||||
assert_eq!(
|
||||
|
|
@ -295,7 +295,7 @@ struct EmptyStruct;
|
|||
|
||||
fn test_empty_struct() {
|
||||
let bytes = vec![0, 0, 0, 0];
|
||||
let buffer = BitReadBuffer::new(bytes, BigEndian);
|
||||
let buffer = BitReadBuffer::new(&bytes, BigEndian);
|
||||
let mut stream = BitReadStream::from(buffer);
|
||||
assert_eq!(EmptyStruct, stream.read().unwrap());
|
||||
assert_eq!(0, stream.pos());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue