Compare commits
4 Commits
5f238c7bc4
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| c8a5faa1e9 | |||
| b3bf6dcac1 | |||
| 456ff355ed | |||
| fc244b8f81 |
@@ -7,5 +7,4 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.81"
|
|
||||||
poppable-derive = { path = "poppable-derive"}
|
poppable-derive = { path = "poppable-derive"}
|
||||||
|
|||||||
@@ -5,7 +5,24 @@ use quote::{quote, quote_spanned};
|
|||||||
use syn::{spanned::Spanned, DeriveInput};
|
use syn::{spanned::Spanned, DeriveInput};
|
||||||
|
|
||||||
#[proc_macro_derive(PushPopParse)]
|
#[proc_macro_derive(PushPopParse)]
|
||||||
pub fn pushpop_derive_macro(item: TokenStream) -> TokenStream {
|
pub fn poppable_derive_macro(item: TokenStream) -> TokenStream {
|
||||||
|
let mut pop_from_ne = pop_ne_derive_macro(item.clone());
|
||||||
|
let pop_from_le = pop_le_derive_macro(item.clone());
|
||||||
|
let pop_from_be = pop_be_derive_macro(item);
|
||||||
|
|
||||||
|
pop_from_ne.extend([pop_from_le, pop_from_be]);
|
||||||
|
pop_from_ne
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! pop_derive_macro {
|
||||||
|
(
|
||||||
|
$fn_name:ident,
|
||||||
|
$trait_name:ident,
|
||||||
|
$trait_pop_fn:ident,
|
||||||
|
$trait_push_fn:ident
|
||||||
|
) => {
|
||||||
|
#[proc_macro_derive($trait_name)]
|
||||||
|
pub fn $fn_name(item: TokenStream) -> TokenStream {
|
||||||
let ast: DeriveInput = syn::parse(item).unwrap();
|
let ast: DeriveInput = syn::parse(item).unwrap();
|
||||||
let struct_ident = ast.ident;
|
let struct_ident = ast.ident;
|
||||||
let struct_data: syn::DataStruct = match ast.data {
|
let struct_data: syn::DataStruct = match ast.data {
|
||||||
@@ -17,7 +34,7 @@ pub fn pushpop_derive_macro(item: TokenStream) -> TokenStream {
|
|||||||
let recursive = struct_data.fields.iter().map(|f| {
|
let recursive = struct_data.fields.iter().map(|f| {
|
||||||
let name = &f.ident;
|
let name = &f.ident;
|
||||||
let ty = &f.ty;
|
let ty = &f.ty;
|
||||||
quote_spanned!(f.span()=> let #name = #ty::pop_ne_from(&mut source)?;)
|
quote_spanned!(f.span()=> let #name = <#ty>::$trait_pop_fn(&mut source)?;)
|
||||||
});
|
});
|
||||||
|
|
||||||
let names = struct_data.fields.iter().map(|f| {
|
let names = struct_data.fields.iter().map(|f| {
|
||||||
@@ -26,12 +43,12 @@ pub fn pushpop_derive_macro(item: TokenStream) -> TokenStream {
|
|||||||
});
|
});
|
||||||
let pop = struct_data.fields.iter().map(|f| {
|
let pop = struct_data.fields.iter().map(|f| {
|
||||||
let name = &f.ident;
|
let name = &f.ident;
|
||||||
quote_spanned!(f.span()=> PopFromNE::push_ne_into(&self.#name, dest)?;)
|
quote_spanned!(f.span()=> $trait_name::$trait_push_fn(&self.#name, dest)?;)
|
||||||
});
|
});
|
||||||
|
|
||||||
quote!(
|
quote!(
|
||||||
impl PopFromNE for #struct_ident {
|
impl $trait_name for #struct_ident {
|
||||||
fn pop_ne_from(mut source: &mut &[u8]) -> Result<Self>
|
fn $trait_pop_fn(mut source: &mut &[u8]) -> std::io::Result<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@@ -40,10 +57,16 @@ pub fn pushpop_derive_macro(item: TokenStream) -> TokenStream {
|
|||||||
#(#names),*
|
#(#names),*
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn push_ne_into<T: Pushable>(&self, dest: &mut T) -> Result<()> {
|
fn $trait_push_fn<T: Pushable>(&self, dest: &mut T) -> std::io::Result<()> {
|
||||||
#(#pop)*
|
#(#pop)*
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into()
|
.into()
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pop_derive_macro!(pop_ne_derive_macro, PopFromNE, pop_ne_from, push_ne_into);
|
||||||
|
pop_derive_macro!(pop_le_derive_macro, PopFromLE, pop_le_from, push_le_into);
|
||||||
|
pop_derive_macro!(pop_be_derive_macro, PopFromBE, pop_be_from, push_be_into);
|
||||||
|
|||||||
38
src/lib.rs
38
src/lib.rs
@@ -1,5 +1,6 @@
|
|||||||
use anyhow::{Ok, Result};
|
//use anyhow::{Ok, Result};
|
||||||
pub use poppable_derive::PushPopParse;
|
pub use poppable_derive::PushPopParse;
|
||||||
|
use std::io::{self, Result};
|
||||||
|
|
||||||
//pub type BytesRef = AsRef<u8>;
|
//pub type BytesRef = AsRef<u8>;
|
||||||
|
|
||||||
@@ -79,7 +80,10 @@ impl PopFromNE for u8 {
|
|||||||
{
|
{
|
||||||
const SIZE: usize = std::mem::size_of::<u8>();
|
const SIZE: usize = std::mem::size_of::<u8>();
|
||||||
if source.len() < SIZE {
|
if source.len() < SIZE {
|
||||||
anyhow::bail!("Buffer too small to pop u8");
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
"Buffer too small to pop u8",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let value = source[0];
|
let value = source[0];
|
||||||
@@ -126,9 +130,12 @@ macro_rules! core_impl_pop_ne {
|
|||||||
{
|
{
|
||||||
const SIZE: usize = std::mem::size_of::<$int_type>();
|
const SIZE: usize = std::mem::size_of::<$int_type>();
|
||||||
if source.len() < SIZE {
|
if source.len() < SIZE {
|
||||||
anyhow::bail!("Buffer too small to pop {}", stringify!($int_type));
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
stringify!(Buffer too small to pop $int_type),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let value = $int_type::from_ne_bytes(source[..SIZE].try_into()?);
|
let value = $int_type::from_ne_bytes(source[..SIZE].try_into().unwrap());
|
||||||
*source = &source[SIZE..];
|
*source = &source[SIZE..];
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
@@ -176,9 +183,12 @@ macro_rules! flt_impl_pop_non_ne {
|
|||||||
{
|
{
|
||||||
const SIZE: usize = std::mem::size_of::<$flt_type>();
|
const SIZE: usize = std::mem::size_of::<$flt_type>();
|
||||||
if source.len() < SIZE {
|
if source.len() < SIZE {
|
||||||
anyhow::bail!("Buffer to small to pop $flt_type");
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
stringify!(Buffer too small to pop $flt_type),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let value = $flt_type::from_le_bytes(source[..SIZE].try_into()?);
|
let value = $flt_type::from_le_bytes(source[..SIZE].try_into().unwrap());
|
||||||
*source = &source[SIZE..];
|
*source = &source[SIZE..];
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
@@ -194,9 +204,12 @@ macro_rules! flt_impl_pop_non_ne {
|
|||||||
{
|
{
|
||||||
const SIZE: usize = std::mem::size_of::<$flt_type>();
|
const SIZE: usize = std::mem::size_of::<$flt_type>();
|
||||||
if source.len() < SIZE {
|
if source.len() < SIZE {
|
||||||
anyhow::bail!("Buffer to small to pop $flt_type");
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
stringify!(Buffer too small to pop $flt_type),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let value = $flt_type::from_be_bytes(source[..SIZE].try_into()?);
|
let value = $flt_type::from_be_bytes(source[..SIZE].try_into().unwrap());
|
||||||
*source = &source[SIZE..];
|
*source = &source[SIZE..];
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
@@ -242,9 +255,14 @@ impl<const SIZE: usize> PopFromNE for [u8; SIZE] {
|
|||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
if source.len() < SIZE {
|
if source.len() < SIZE {
|
||||||
anyhow::bail!("Buffer to small to pop [u8; {SIZE}]");
|
//anyhow::bail!("Buffer to small to pop [u8; {SIZE}]");
|
||||||
|
return Err(io::Error::new(
|
||||||
|
io::ErrorKind::UnexpectedEof,
|
||||||
|
format!("Buffer too small to pop [u8; {SIZE}]"),
|
||||||
|
//stringify!(Buffer too small to pop $flt_type),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
let value = source[..SIZE].try_into()?;
|
let value = source[..SIZE].try_into().unwrap();
|
||||||
*source = &source[SIZE..];
|
*source = &source[SIZE..];
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user