mod code_gen;
pub mod error;
mod model_types;
pub mod parsely_read;
pub mod parsely_write;
pub(crate) mod syn_helpers;
pub use bits_io::{
buf::bit_buf::BitBuf,
buf::bit_buf_exts::BitBufExts,
buf::bit_buf_mut::BitBufMut,
buf::bit_buf_mut_exts::BitBufMutExts,
buf::bits::Bits,
buf::bits_mut::BitsMut,
buf::byte_order::{BigEndian, ByteOrder, LittleEndian, NetworkOrder},
io::{bit_cursor::BitCursor, bit_read::BitRead, bit_write::BitWrite},
};
pub mod nsw_types {
pub use bits_io::nsw_types::from_bitslice::BitSliceUxExts;
pub use bits_io::nsw_types::*;
}
pub mod anyhow {
pub use anyhow::*;
}
use code_gen::{
read::{
parsely_read_enum_data::ParselyReadEnumData,
parsely_read_struct_data::ParselyReadStructData,
},
write::{
parsely_write_enum_data::ParselyWriteEnumData,
parsely_write_struct_data::ParselyWriteStructData,
},
};
use darling::{ast, FromDeriveInput, FromField, FromMeta, FromVariant};
use model_types::{Assertion, Context, ExprOrFunc, MapExpr, TypedFnArgList};
use proc_macro2::TokenStream;
use quote::quote;
use syn::DeriveInput;
use syn_helpers::TypeExts;
#[doc(hidden)]
pub fn derive_parsely_read(item: TokenStream) -> std::result::Result<TokenStream, syn::Error> {
let ast: DeriveInput = syn::parse2(item)?;
let data = ParselyReadReceiver::from_derive_input(&ast)?;
if data.data.is_struct() {
let struct_data = ParselyReadStructData::try_from(data).unwrap();
Ok(quote! {
#struct_data
})
} else {
let enum_data = ParselyReadEnumData::try_from(data).unwrap();
Ok(quote! {
#enum_data
})
}
}
#[doc(hidden)]
pub fn derive_parsely_write(item: TokenStream) -> std::result::Result<TokenStream, syn::Error> {
let ast: DeriveInput = syn::parse2(item)?;
let data = ParselyWriteReceiver::from_derive_input(&ast)?;
if data.data.is_struct() {
let struct_data = ParselyWriteStructData::try_from(data).unwrap();
Ok(quote! {
#struct_data
})
} else {
let enum_data = ParselyWriteEnumData::try_from(data).unwrap();
Ok(quote! {
#enum_data
})
}
}
#[derive(Debug, FromField, FromMeta)]
pub struct ParselyCommonFieldReceiver {
assertion: Option<Assertion>,
context: Option<Context>,
map: Option<MapExpr>,
alignment: Option<usize>,
}
#[derive(Debug, FromField)]
#[darling(attributes(parsely, parsely_read))]
pub struct ParselyReadFieldReceiver {
ident: Option<syn::Ident>,
ty: syn::Type,
#[darling(flatten)]
common: ParselyCommonFieldReceiver,
count: Option<syn::Expr>,
while_pred: Option<syn::Expr>,
assign_from: Option<syn::Expr>,
when: Option<syn::Expr>,
}
#[derive(Debug, FromVariant)]
#[darling(attributes(parsely, parsely_read))]
pub struct ParselyReadVariantReceiver {
ident: syn::Ident,
discriminant: Option<syn::Expr>,
id: syn::Expr,
fields: ast::Fields<ParselyReadFieldReceiver>,
}
#[derive(Debug, FromField)]
#[darling(attributes(parsely, parsely_write))]
pub struct ParselyWriteFieldReceiver {
ident: Option<syn::Ident>,
ty: syn::Type,
#[darling(flatten)]
common: ParselyCommonFieldReceiver,
sync_expr: Option<ExprOrFunc>,
#[darling(default)]
sync_with: Context,
}
#[derive(Debug, FromVariant)]
#[darling(attributes(parsely, parsely_write))]
pub struct ParselyWriteVariantReceiver {
ident: syn::Ident,
discriminant: Option<syn::Expr>,
id: syn::Expr,
fields: ast::Fields<ParselyWriteFieldReceiver>,
}
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(parsely, parsely_read), supports(struct_any, enum_any))]
pub struct ParselyReadReceiver {
ident: syn::Ident,
#[darling(default)]
required_context: TypedFnArgList,
alignment: Option<usize>,
key_type: Option<syn::Type>,
data: ast::Data<ParselyReadVariantReceiver, ParselyReadFieldReceiver>,
}
#[derive(Debug, FromDeriveInput)]
#[darling(attributes(parsely, parsely_write), supports(struct_any, enum_any))]
pub struct ParselyWriteReceiver {
ident: syn::Ident,
#[darling(default)]
required_context: TypedFnArgList,
#[darling(default)]
sync_args: TypedFnArgList,
alignment: Option<usize>,
key_type: Option<syn::Type>,
data: ast::Data<ParselyWriteVariantReceiver, ParselyWriteFieldReceiver>,
}
pub(crate) fn get_crate_name() -> syn::Ident {
let found_crate =
proc_macro_crate::crate_name("parsely-rs").expect("parsely-rs is present in Cargo.toml");
let crate_name = match found_crate {
proc_macro_crate::FoundCrate::Itself => "parsely_rs".to_string(),
proc_macro_crate::FoundCrate::Name(name) => name,
};
syn::Ident::new(&crate_name, proc_macro2::Span::call_site())
}