1mod code_gen;
2pub mod error;
3mod model_types;
4pub mod parsely_read;
5pub mod parsely_write;
6pub(crate) mod syn_helpers;
7
8pub use bits_io::{
9 buf::bit_buf::BitBuf,
10 buf::bit_buf_exts::BitBufExts,
11 buf::bit_buf_mut::BitBufMut,
12 buf::bit_buf_mut_exts::BitBufMutExts,
13 buf::bits::Bits,
14 buf::bits_mut::BitsMut,
15 buf::byte_order::{BigEndian, ByteOrder, LittleEndian, NetworkOrder},
16 io::{bit_cursor::BitCursor, bit_read::BitRead, bit_write::BitWrite},
17};
18
19pub mod nsw_types {
20 pub use bits_io::nsw_types::from_bitslice::BitSliceUxExts;
21 pub use bits_io::nsw_types::*;
22}
23
24pub mod anyhow {
25 pub use anyhow::*;
26}
27
28use code_gen::{
29 read::{
30 parsely_read_enum_data::ParselyReadEnumData,
31 parsely_read_struct_data::ParselyReadStructData,
32 },
33 write::{
34 parsely_write_enum_data::ParselyWriteEnumData,
35 parsely_write_struct_data::ParselyWriteStructData,
36 },
37};
38use darling::{ast, FromDeriveInput, FromField, FromMeta, FromVariant};
39use model_types::{Assertion, Context, ExprOrFunc, MapExpr, TypedFnArgList};
40use proc_macro2::TokenStream;
41use quote::quote;
42use syn::DeriveInput;
43use syn_helpers::TypeExts;
44
45#[doc(hidden)]
46pub fn derive_parsely_read(item: TokenStream) -> std::result::Result<TokenStream, syn::Error> {
47 let ast: DeriveInput = syn::parse2(item)?;
48 let data = ParselyReadReceiver::from_derive_input(&ast)?;
49
50 if data.data.is_struct() {
53 let struct_data = ParselyReadStructData::try_from(data).unwrap();
54 Ok(quote! {
55 #struct_data
56 })
57 } else {
58 let enum_data = ParselyReadEnumData::try_from(data).unwrap();
59 Ok(quote! {
60 #enum_data
61 })
62 }
63}
64
65#[doc(hidden)]
66pub fn derive_parsely_write(item: TokenStream) -> std::result::Result<TokenStream, syn::Error> {
67 let ast: DeriveInput = syn::parse2(item)?;
68 let data = ParselyWriteReceiver::from_derive_input(&ast)?;
69
70 if data.data.is_struct() {
71 let struct_data = ParselyWriteStructData::try_from(data).unwrap();
72 Ok(quote! {
73 #struct_data
74 })
75 } else {
76 let enum_data = ParselyWriteEnumData::try_from(data).unwrap();
77 Ok(quote! {
78 #enum_data
79 })
80 }
81}
82
83#[derive(Debug, FromField, FromMeta)]
84pub struct ParselyCommonFieldReceiver {
85 assertion: Option<Assertion>,
90
91 context: Option<Context>,
93
94 map: Option<MapExpr>,
96
97 alignment: Option<usize>,
100}
101
102#[derive(Debug, FromField)]
103#[darling(attributes(parsely, parsely_read))]
104pub struct ParselyReadFieldReceiver {
105 ident: Option<syn::Ident>,
106
107 ty: syn::Type,
108
109 #[darling(flatten)]
110 common: ParselyCommonFieldReceiver,
111 count: Option<syn::Expr>,
113 while_pred: Option<syn::Expr>,
117
118 assign_from: Option<syn::Expr>,
121
122 when: Option<syn::Expr>,
124}
125
126#[derive(Debug, FromVariant)]
127#[darling(attributes(parsely, parsely_read))]
128pub struct ParselyReadVariantReceiver {
129 ident: syn::Ident,
130 discriminant: Option<syn::Expr>,
131 id: syn::Expr,
132 fields: ast::Fields<ParselyReadFieldReceiver>,
133}
134
135#[derive(Debug, FromField)]
136#[darling(attributes(parsely, parsely_write))]
137pub struct ParselyWriteFieldReceiver {
138 ident: Option<syn::Ident>,
139
140 ty: syn::Type,
141
142 #[darling(flatten)]
143 common: ParselyCommonFieldReceiver,
144
145 sync_expr: Option<ExprOrFunc>,
148
149 #[darling(default)]
153 sync_with: Context,
154}
155
156#[derive(Debug, FromVariant)]
157#[darling(attributes(parsely, parsely_write))]
158pub struct ParselyWriteVariantReceiver {
159 ident: syn::Ident,
160 discriminant: Option<syn::Expr>,
161 id: syn::Expr,
162 fields: ast::Fields<ParselyWriteFieldReceiver>,
163}
164
165#[derive(Debug, FromDeriveInput)]
166#[darling(attributes(parsely, parsely_read), supports(struct_any, enum_any))]
167pub struct ParselyReadReceiver {
168 ident: syn::Ident,
169 #[darling(default)]
170 required_context: TypedFnArgList,
171 alignment: Option<usize>,
172 key_type: Option<syn::Type>,
174 data: ast::Data<ParselyReadVariantReceiver, ParselyReadFieldReceiver>,
175}
176
177#[derive(Debug, FromDeriveInput)]
178#[darling(attributes(parsely, parsely_write), supports(struct_any, enum_any))]
179pub struct ParselyWriteReceiver {
180 ident: syn::Ident,
181 #[darling(default)]
182 required_context: TypedFnArgList,
183 #[darling(default)]
184 sync_args: TypedFnArgList,
185 alignment: Option<usize>,
186 key_type: Option<syn::Type>,
188 data: ast::Data<ParselyWriteVariantReceiver, ParselyWriteFieldReceiver>,
189}
190
191pub(crate) fn get_crate_name() -> syn::Ident {
192 let found_crate =
193 proc_macro_crate::crate_name("parsely-rs").expect("parsely-rs is present in Cargo.toml");
194
195 let crate_name = match found_crate {
196 proc_macro_crate::FoundCrate::Itself => "parsely_rs".to_string(),
197 proc_macro_crate::FoundCrate::Name(name) => name,
198 };
199
200 syn::Ident::new(&crate_name, proc_macro2::Span::call_site())
201}