afastdata_macro/lib.rs
1//! # afastdata-macro
2//!
3//! afastdata 序列化框架的 derive 宏,为结构体和枚举自动生成
4//! [`AFastSerialize`] 和 [`AFastDeserialize`] trait 的实现。
5//!
6//! Derive macros for the afastdata serialization framework, automatically generating
7//! implementations of [`AFastSerialize`]` and [`AFastDeserialize`] traits for
8//! structs and enums.
9//!
10//! ## 支持的类型 / Supported Types
11//!
12//! - **命名字段结构体 (Named-field struct)**:逐字段序列化/反序列化
13//! / Field-by-field serialization/deserialization
14//! - **元组结构体 (Tuple struct)**:按索引逐字段序列化/反序列化
15//! / Index-based field serialization/deserialization
16//! - **单元结构体 (Unit struct)**:生成空实现(不产生任何字节)
17//! / Generates an empty implementation (no bytes produced)
18//! - **枚举 (Enum)**:写入变体标签 + 变体字段数据(标签类型可通过 feature 切换)
19//! / Writes a variant tag + variant field data (tag type switchable via features)
20//!
21//! ## 编码格式 / Encoding Format
22//!
23//! ### 结构体 / Struct
24//!
25//! 所有字段按声明顺序依次调用 `to_bytes()` / `from_bytes()`,无额外前缀。
26//!
27//! All fields call `to_bytes()` / `from_bytes()` in declaration order, with no
28//! additional prefix.
29//!
30//! ### 枚举 / Enum
31//!
32//! | 编码内容 / Content | 类型 / Type | 说明 / Description |
33//! |---|---|---|
34//! | 变体索引 / Variant index | `u8`/`u16`/`u32` little-endian | 默认 `u8`,从 0 开始递增;通过 `tag-u16`/`tag-u32` feature 切换 / Default `u8`, starts from 0; switchable via `tag-u16`/`tag-u32` features |
35//! | 变体字段 / Variant fields | 逐字段编码 / Field-wise encoding | 仅非 unit 变体 / Only for non-unit variants |
36//!
37//! ## 泛型支持 / Generic Support
38//!
39//! 泛型参数会自动添加 `AFastSerialize` 和(对于反序列化)`AFastDeserialize` trait 约束。
40//! 如果泛型参数仅用于某些字段,生成的约束可能过于严格,但这保证了实现的正确性。
41//!
42//! Generic parameters automatically receive `AFastSerialize` and (for deserialization)
43//! `AFastDeserialize` trait bounds. If a generic parameter is only used in certain fields,
44//! the generated bounds may be overly strict, but this ensures correctness.
45//!
46//! ## 示例 / Example
47//!
48//! ```
49//! extern crate afastdata;
50//! use afastdata::{AFastSerialize, AFastDeserialize};
51//!
52//! #[derive(AFastSerialize, AFastDeserialize, Debug, PartialEq)]
53//! struct Point {
54//! x: i32,
55//! y: i32,
56//! }
57//!
58//! #[derive(AFastSerialize, AFastDeserialize, Debug, PartialEq)]
59//! enum Shape {
60//! Circle(f64),
61//! Rectangle { width: f64, height: f64 },
62//! Empty,
63//! }
64//!
65//! // 序列化 / Serialize
66//! let point = Point { x: 10, y: 20 };
67//! let bytes = point.to_bytes();
68//!
69//! // 反序列化 / Deserialize
70//! let (decoded, _) = Point::from_bytes(&bytes).unwrap();
71//! assert_eq!(point, decoded);
72//! ```
73
74use proc_macro::TokenStream;
75use quote::quote;
76use syn::{
77 Attribute, Data, DeriveInput, Fields, Index, Lit, LitFloat, LitInt, LitStr, Meta, Path, Token,
78 Type, TypePath,
79 parse::{Parse, ParseStream},
80 parse_macro_input,
81 punctuated::Punctuated,
82};
83
84/// 返回枚举变体标签的类型和字节大小,基于编译时 feature 配置。
85///
86/// Returns the enum variant tag type and byte size based on compile-time feature config.
87fn tag_type() -> (proc_macro2::TokenStream, usize) {
88 if cfg!(feature = "tag-u16") {
89 (quote! { u16 }, 2)
90 } else if cfg!(feature = "tag-u32") {
91 (quote! { u32 }, 4)
92 } else {
93 (quote! { u8 }, 1)
94 }
95}
96
97/// 为结构体或枚举生成 [`AFastSerialize`] trait 实现。
98///
99/// Generates an [`AFastSerialize`] trait implementation for a struct or enum.
100///
101/// # 生成的代码 / Generated Code
102///
103/// ## 结构体 / Struct
104///
105/// 为每个字段调用 `to_bytes()`,并将结果依次追加到字节缓冲区中。
106///
107/// Calls `to_bytes()` on each field, appending the results to a byte buffer
108/// sequentially.
109///
110/// ```text
111/// // 以下为生成代码的示意(非实际代码)
112/// // The following is an illustration of generated code (not actual code)
113/// impl AFastSerialize for MyStruct {
114/// fn to_bytes(&self) -> Vec<u8> {
115/// let mut bytes = Vec::new();
116/// bytes.extend(AFastSerialize::to_bytes(&self.field1));
117/// bytes.extend(AFastSerialize::to_bytes(&self.field2));
118/// // ... 依次处理每个字段 / remaining fields processed similarly
119/// bytes
120/// }
121/// }
122/// ```
123///
124/// ## 枚举 / Enum
125///
126/// 先写入 `u8` 变体索引(从 0 开始),再写入变体的字段数据。
127/// Unit 变体只写入索引。可通过 feature 切换为 `u16` 或 `u32`。
128///
129/// Writes a `u8` variant index (starting from 0), then the variant's field data.
130/// Unit variants only write the index. Switchable to `u16` or `u32` via features.
131///
132/// ```text
133/// // 以下为生成代码的示意(非实际代码)
134/// // The following is an illustration of generated code (not actual code)
135/// impl AFastSerialize for MyEnum {
136/// fn to_bytes(&self) -> Vec<u8> {
137/// let mut bytes = Vec::new();
138/// match self {
139/// MyEnum::Variant1 => {
140/// bytes.extend(0u8.to_le_bytes());
141/// }
142/// MyEnum::Variant2(field) => {
143/// bytes.extend(1u8.to_le_bytes());
144/// bytes.extend(AFastSerialize::to_bytes(field));
145/// }
146/// // ...
147/// }
148/// bytes
149/// }
150/// }
151/// ```
152///
153/// # 泛型 / Generics
154///
155/// 如果目标类型包含泛型参数,生成的 `impl` 会自动为这些参数添加
156/// `AFastSerialize` 约束。
157///
158/// If the target type contains generic parameters, the generated `impl` automatically
159/// adds `AFastSerialize` bounds to those parameters.
160///
161/// # Panics
162///
163/// 对 union 类型使用此宏会触发编译 panic。
164///
165/// Using this macro on a union type will trigger a compile-time panic.
166#[proc_macro_derive(AFastSerialize, attributes(afast))]
167pub fn derive_serialize(input: TokenStream) -> TokenStream {
168 let input = parse_macro_input!(input as DeriveInput);
169 let name = &input.ident;
170 let generics = &input.generics;
171
172 // 为泛型参数添加 AFastSerialize trait 约束
173 // Add AFastSerialize trait bounds to generic parameters
174 let mut generics_with_bounds = generics.clone();
175 for param in &mut generics_with_bounds.params {
176 if let syn::GenericParam::Type(ref mut ty) = *param {
177 ty.bounds
178 .push(syn::parse_quote!(::afastdata::AFastSerialize));
179 }
180 }
181 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
182 let (_, ty_generics, _) = generics.split_for_impl();
183
184 let expanded = match &input.data {
185 Data::Struct(data) => {
186 let serialize_body = generate_serialize_fields(&data.fields, quote!(self));
187 let marker_ident = syn::Ident::new("__afast_marker__", proc_macro2::Span::call_site());
188 let serialize_body_with =
189 generate_serialize_fields_with(&data.fields, quote!(self), &marker_ident);
190 quote! {
191 impl #impl_generics ::afastdata::AFastSerialize for #name #ty_generics {
192 fn to_bytes(&self) -> Vec<u8> {
193 let mut __afast_bytes__ = Vec::new();
194 #(#serialize_body)*
195 __afast_bytes__
196 }
197 fn to_bytes_with(&self, __afast_marker__: &str) -> Vec<u8> {
198 let mut __afast_bytes__ = Vec::new();
199 #(#serialize_body_with)*
200 __afast_bytes__
201 }
202 }
203 }
204 }
205 Data::Enum(data) => {
206 let (tag_ty, _) = tag_type();
207 let mut arms = Vec::new();
208 let mut arms_with = Vec::new();
209 for (i, variant) in data.variants.iter().enumerate() {
210 let variant_name = &variant.ident;
211
212 match &variant.fields {
213 Fields::Unit => {
214 arms.push(quote! {
215 #name::#variant_name => {
216 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
217 }
218 });
219 arms_with.push(quote! {
220 #name::#variant_name => {
221 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
222 }
223 });
224 }
225 Fields::Unnamed(fields) => {
226 let field_names: Vec<_> = (0..fields.unnamed.len())
227 .map(|i| syn::Ident::new(&format!("__f{}", i), variant_name.span()))
228 .collect();
229 let field_patterns = &field_names;
230 let mut serialize_fields = Vec::new();
231 for (i, f) in fields.unnamed.iter().enumerate() {
232 if !has_skip_attr(&f.attrs).0 {
233 let fname = &field_names[i];
234 serialize_fields.push(quote! {
235 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes(#fname));
236 });
237 }
238 }
239 let mut serialize_fields_with = Vec::new();
240 for (i, f) in fields.unnamed.iter().enumerate() {
241 if has_skip_attr(&f.attrs).0 {
242 continue;
243 }
244 let skip_with = has_skip_with_attr(&f.attrs);
245 let fname = &field_names[i];
246 if let Some((m, _)) = skip_with {
247 serialize_fields_with.push(quote! {
248 if #m != __afast_marker__ {
249 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(#fname, __afast_marker__));
250 }
251 });
252 } else {
253 serialize_fields_with.push(quote! {
254 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(#fname, __afast_marker__));
255 });
256 }
257 }
258 arms.push(quote! {
259 #name::#variant_name(#(#field_patterns),*) => {
260 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
261 #(#serialize_fields)*
262 }
263 });
264 arms_with.push(quote! {
265 #name::#variant_name(#(#field_patterns),*) => {
266 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
267 #(#serialize_fields_with)*
268 }
269 });
270 }
271 Fields::Named(fields) => {
272 let all_field_names: Vec<_> = fields
273 .named
274 .iter()
275 .map(|f| f.ident.as_ref().unwrap())
276 .collect();
277 let non_skip_names: Vec<_> = fields
278 .named
279 .iter()
280 .filter(|f| !has_skip_attr(&f.attrs).0)
281 .map(|f| f.ident.as_ref().unwrap())
282 .collect();
283 let has_skip = non_skip_names.len() < all_field_names.len();
284 let mut serialize_fields = Vec::new();
285 for fname in &non_skip_names {
286 serialize_fields.push(quote! {
287 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes(#fname));
288 });
289 }
290 // _with: include all non-skip fields, skip_with matched ones use runtime check
291 let non_skip_fields_with: Vec<_> = fields
292 .named
293 .iter()
294 .filter(|f| !has_skip_attr(&f.attrs).0)
295 .collect();
296 let has_any_skip_with = non_skip_fields_with.len() < all_field_names.len();
297 let non_skip_names_with: Vec<_> = non_skip_fields_with
298 .iter()
299 .map(|f| f.ident.as_ref().unwrap())
300 .collect();
301 let mut serialize_fields_with = Vec::new();
302 for f in &non_skip_fields_with {
303 let fname = f.ident.as_ref().unwrap();
304 let skip_with = has_skip_with_attr(&f.attrs);
305 if let Some((m, _)) = skip_with {
306 serialize_fields_with.push(quote! {
307 if #m != __afast_marker__ {
308 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(#fname, __afast_marker__));
309 }
310 });
311 } else {
312 serialize_fields_with.push(quote! {
313 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(#fname, __afast_marker__));
314 });
315 }
316 }
317 if has_skip {
318 arms.push(quote! {
319 #name::#variant_name { #(#non_skip_names),*, .. } => {
320 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
321 #(#serialize_fields)*
322 }
323 });
324 } else {
325 arms.push(quote! {
326 #name::#variant_name { #(#non_skip_names),* } => {
327 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
328 #(#serialize_fields)*
329 }
330 });
331 }
332 if has_any_skip_with {
333 arms_with.push(quote! {
334 #name::#variant_name { #(#non_skip_names_with),*, .. } => {
335 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
336 #(#serialize_fields_with)*
337 }
338 });
339 } else {
340 arms_with.push(quote! {
341 #name::#variant_name { #(#non_skip_names_with),* } => {
342 __afast_bytes__.extend((#i as #tag_ty).to_le_bytes());
343 #(#serialize_fields_with)*
344 }
345 });
346 }
347 }
348 }
349 }
350
351 quote! {
352 impl #impl_generics ::afastdata::AFastSerialize for #name #ty_generics {
353 fn to_bytes(&self) -> Vec<u8> {
354 let mut __afast_bytes__ = Vec::new();
355 match self {
356 #(#arms)*
357 }
358 __afast_bytes__
359 }
360 fn to_bytes_with(&self, __afast_marker__: &str) -> Vec<u8> {
361 let mut __afast_bytes__ = Vec::new();
362 match self {
363 #(#arms_with)*
364 }
365 __afast_bytes__
366 }
367 }
368 }
369 }
370 Data::Union(_) => panic!("AFastSerialize does not support unions"),
371 };
372
373 TokenStream::from(expanded)
374}
375
376/// 为结构体或枚举生成 [`AFastDeserialize`] trait 实现。
377///
378/// Generates an [`AFastDeserialize`] trait implementation for a struct or enum.
379///
380/// # 生成的代码 / Generated Code
381///
382/// ## 结构体 / Struct
383///
384/// 为每个字段依次调用 `from_bytes()`,并使用偏移量追踪已消耗的字节数,
385/// 最后构造结构体实例。
386///
387/// Calls `from_bytes()` on each field sequentially, using an offset to track
388/// consumed bytes, then constructs the struct instance.
389///
390/// ```text
391/// // 以下为生成代码的示意(非实际代码)
392/// // The following is an illustration of generated code (not actual code)
393/// impl AFastDeserialize for MyStruct {
394/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
395/// let mut offset: usize = 0;
396/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
397/// let field1 = __val;
398/// offset += __new_offset;
399/// // ... 更多字段 / more fields ...
400/// Ok((MyStruct { field1, ... }, offset))
401/// }
402/// }
403/// ```
404///
405/// ## 枚举 / Enum
406///
407/// 先读取 `u8` 变体索引,根据索引匹配对应变体,再反序列化该变体的字段。
408/// 可通过 feature 切换为 `u16` 或 `u32`。
409///
410/// First reads the `u8` variant index, matches the corresponding variant by index,
411/// then deserializes the variant's fields.
412/// Switchable to `u16` or `u32` via features.
413///
414/// ```text
415/// // 以下为生成代码的示意(非实际代码)
416/// // The following is an illustration of generated code (not actual code)
417/// impl AFastDeserialize for MyEnum {
418/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
419/// let mut offset: usize = 0;
420/// let (__tag, __new_offset) = <u8 as AFastDeserialize>::from_bytes(&data[offset..])?;
421/// offset += __new_offset;
422/// match __tag as usize {
423/// 0 => Ok((MyEnum::Variant1, offset)),
424/// 1 => {
425/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
426/// offset += __new_offset;
427/// Ok((MyEnum::Variant2(__val), offset))
428/// }
429/// v => Err(format!("Unknown variant tag: {} for MyEnum", v)),
430/// }
431/// }
432/// }
433/// ```
434///
435/// # 泛型 / Generics
436///
437/// 如果目标类型包含泛型参数,生成的 `impl` 会同时添加 `AFastSerialize` 和
438/// `AFastDeserialize` 约束。双重约束确保泛型类型在序列化和反序列化两个方向
439/// 上都可用。
440///
441/// If the target type contains generic parameters, the generated `impl` adds both
442/// `AFastSerialize` and `AFastDeserialize` bounds. The dual bounds ensure the generic
443/// type is available in both serialization and deserialization directions.
444///
445/// # Panics
446///
447/// 对 union 类型使用此宏会触发编译 panic。
448///
449/// Using this macro on a union type will trigger a compile-time panic.
450#[proc_macro_derive(AFastDeserialize, attributes(afast))]
451pub fn derive_deserialize(input: TokenStream) -> TokenStream {
452 let input = parse_macro_input!(input as DeriveInput);
453 let name = &input.ident;
454 let generics = &input.generics;
455
456 // 为泛型参数添加 AFastSerialize + AFastDeserialize trait 约束
457 // Add AFastSerialize + AFastDeserialize trait bounds to generic parameters
458 let mut generics_with_bounds = generics.clone();
459 for param in &mut generics_with_bounds.params {
460 if let syn::GenericParam::Type(ref mut ty) = *param {
461 ty.bounds
462 .push(syn::parse_quote!(::afastdata::AFastSerialize));
463 ty.bounds
464 .push(syn::parse_quote!(::afastdata::AFastDeserialize));
465 }
466 }
467 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
468 let (_, ty_generics, _) = generics.split_for_impl();
469
470 let expanded = match &input.data {
471 Data::Struct(data) => {
472 let (construct, field_desers) =
473 generate_deserialize_fields(&data.fields, name, &ty_generics);
474 let (construct_with, field_desers_with) = generate_deserialize_fields_with(
475 &data.fields,
476 name,
477 &ty_generics,
478 "__afast_marker__",
479 );
480 quote! {
481 impl #impl_generics ::afastdata::AFastDeserialize for #name #ty_generics {
482 fn from_bytes(__afast_data__: &[u8]) -> Result<(Self, usize), ::afastdata::Error> {
483 let mut __afast_offset__: usize = 0;
484 #(#field_desers)*
485 Ok((#construct, __afast_offset__))
486 }
487 fn from_bytes_with(__afast_data__: &[u8], __afast_marker__: &str) -> Result<(Self, usize), ::afastdata::Error> {
488 let mut __afast_offset__: usize = 0;
489 #(#field_desers_with)*
490 Ok((#construct_with, __afast_offset__))
491 }
492 }
493 }
494 }
495 Data::Enum(data) => {
496 let (tag_ty, _) = tag_type();
497 let mut arms = Vec::new();
498 let mut arms_with = Vec::new();
499 for (i, variant) in data.variants.iter().enumerate() {
500 let variant_name = &variant.ident;
501
502 match &variant.fields {
503 Fields::Unit => {
504 arms.push(quote! {
505 #i => {
506 Ok((#name::#variant_name, __afast_offset__))
507 }
508 });
509 arms_with.push(quote! {
510 #i => {
511 Ok((#name::#variant_name, __afast_offset__))
512 }
513 });
514 }
515 Fields::Unnamed(fields) => {
516 let mut field_desers = Vec::new();
517 let mut field_desers_with = Vec::new();
518 let mut field_names = Vec::new();
519 for (i, f) in fields.unnamed.iter().enumerate() {
520 let fname = syn::Ident::new(&format!("__f{}", i), variant_name.span());
521 let ftype = &f.ty;
522 let (skip, default_fn) = has_skip_attr(&f.attrs);
523 if skip {
524 if let Some(func_name) = default_fn.clone() {
525 match syn::parse_str::<syn::Ident>(&func_name) {
526 Ok(ident) => {
527 field_desers.push(quote! {
528 let #fname: #ftype = #ident();
529 });
530 field_desers_with.push(quote! {
531 let #fname: #ftype = #ident();
532 });
533 }
534 Err(_) => {
535 field_desers.push(quote! {
536 compile_error!(concat!("invalid function name in skip: ", #func_name));
537 });
538 field_desers_with.push(quote! {
539 compile_error!(concat!("invalid function name in skip: ", #func_name));
540 });
541 }
542 }
543 } else {
544 field_desers.push(quote! {
545 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
546 });
547 field_desers_with.push(quote! {
548 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
549 });
550 }
551 } else {
552 let validates = parse_validations(&fname, ftype, &f.attrs);
553 field_desers.push(quote! {
554 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&__afast_data__[__afast_offset__..])?;
555 let #fname: #ftype = __val;
556 #(#validates)*
557 __afast_offset__ += __new_offset;
558 });
559 // _with: check skip_with
560 let skip_with = has_skip_with_attr(&f.attrs);
561 if let Some((m, sw_default)) = skip_with {
562 let default_expr = if let Some(fn_name) = sw_default {
563 match syn::parse_str::<syn::Ident>(&fn_name) {
564 Ok(ident) => quote! { #ident() },
565 Err(_) => {
566 quote! { { compile_error!(concat!("invalid function name in skip_with: ", #fn_name)); <#ftype as ::std::default::Default>::default() } }
567 }
568 }
569 } else {
570 quote! { <#ftype as ::std::default::Default>::default() }
571 };
572 field_desers_with.push(quote! {
573 let #fname: #ftype = if __afast_marker__ == #m {
574 #default_expr
575 } else {
576 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], __afast_marker__)?;
577 #(#validates)*
578 __afast_offset__ += __new_offset;
579 __val
580 };
581 });
582 } else {
583 field_desers_with.push(quote! {
584 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], __afast_marker__)?;
585 let #fname: #ftype = __val;
586 #(#validates)*
587 __afast_offset__ += __new_offset;
588 });
589 }
590 }
591 field_names.push(fname);
592 }
593 arms.push(quote! {
594 #i => {
595 #(#field_desers)*
596 Ok((#name::#variant_name(#(#field_names),*), __afast_offset__))
597 }
598 });
599 arms_with.push(quote! {
600 #i => {
601 #(#field_desers_with)*
602 Ok((#name::#variant_name(#(#field_names),*), __afast_offset__))
603 }
604 });
605 }
606 Fields::Named(fields) => {
607 let mut field_desers = Vec::new();
608 let mut field_desers_with = Vec::new();
609 let mut field_names = Vec::new();
610 for f in &fields.named {
611 let fname = f.ident.as_ref().unwrap();
612 let ftype = &f.ty;
613 let (skip, default_fn) = has_skip_attr(&f.attrs);
614 if skip {
615 if let Some(func_name) = default_fn.clone() {
616 match syn::parse_str::<syn::Ident>(&func_name) {
617 Ok(ident) => {
618 field_desers.push(quote! {
619 let #fname: #ftype = #ident();
620 });
621 field_desers_with.push(quote! {
622 let #fname: #ftype = #ident();
623 });
624 }
625 Err(_) => {
626 field_desers.push(quote! {
627 compile_error!(concat!("invalid function name in skip: ", #func_name));
628 });
629 field_desers_with.push(quote! {
630 compile_error!(concat!("invalid function name in skip: ", #func_name));
631 });
632 }
633 }
634 } else {
635 field_desers.push(quote! {
636 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
637 });
638 field_desers_with.push(quote! {
639 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
640 });
641 }
642 } else {
643 let validates = parse_validations(fname, ftype, &f.attrs);
644 field_desers.push(quote! {
645 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&__afast_data__[__afast_offset__..])?;
646 let #fname: #ftype = __val;
647 #(#validates)*
648 __afast_offset__ += __new_offset;
649 });
650 // _with: check skip_with
651 let skip_with = has_skip_with_attr(&f.attrs);
652 if let Some((m, sw_default)) = skip_with {
653 let default_expr = if let Some(fn_name) = sw_default {
654 match syn::parse_str::<syn::Ident>(&fn_name) {
655 Ok(ident) => quote! { #ident() },
656 Err(_) => {
657 quote! { { compile_error!(concat!("invalid function name in skip_with: ", #fn_name)); <#ftype as ::std::default::Default>::default() } }
658 }
659 }
660 } else {
661 quote! { <#ftype as ::std::default::Default>::default() }
662 };
663 field_desers_with.push(quote! {
664 let #fname: #ftype = if __afast_marker__ == #m {
665 #default_expr
666 } else {
667 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], __afast_marker__)?;
668 #(#validates)*
669 __afast_offset__ += __new_offset;
670 __val
671 };
672 });
673 } else {
674 field_desers_with.push(quote! {
675 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], __afast_marker__)?;
676 let #fname: #ftype = __val;
677 #(#validates)*
678 __afast_offset__ += __new_offset;
679 });
680 }
681 }
682 field_names.push(fname);
683 }
684 arms.push(quote! {
685 #i => {
686 #(#field_desers)*
687 Ok((#name::#variant_name { #(#field_names),* }, __afast_offset__))
688 }
689 });
690 arms_with.push(quote! {
691 #i => {
692 #(#field_desers_with)*
693 Ok((#name::#variant_name { #(#field_names),* }, __afast_offset__))
694 }
695 });
696 }
697 }
698 }
699
700 quote! {
701 impl #impl_generics ::afastdata::AFastDeserialize for #name #ty_generics {
702 fn from_bytes(__afast_data__: &[u8]) -> Result<(Self, usize), ::afastdata::Error> {
703 let mut __afast_offset__: usize = 0;
704 let (__afast_tag__, __new_offset) = <#tag_ty as ::afastdata::AFastDeserialize>::from_bytes(&__afast_data__[__afast_offset__..])?;
705 __afast_offset__ += __new_offset;
706 match __afast_tag__ as usize {
707 #(#arms)*
708 v => Err(::afastdata::Error::deserialize(format!("Unknown variant tag: {} for {}", v, ::std::stringify!(#name)))),
709 }
710 }
711 fn from_bytes_with(__afast_data__: &[u8], __afast_marker__: &str) -> Result<(Self, usize), ::afastdata::Error> {
712 let mut __afast_offset__: usize = 0;
713 let (__afast_tag__, __new_offset) = <#tag_ty as ::afastdata::AFastDeserialize>::from_bytes(&__afast_data__[__afast_offset__..])?;
714 __afast_offset__ += __new_offset;
715 match __afast_tag__ as usize {
716 #(#arms_with)*
717 v => Err(::afastdata::Error::deserialize(format!("Unknown variant tag: {} for {}", v, ::std::stringify!(#name)))),
718 }
719 }
720 }
721 }
722 }
723 Data::Union(_) => panic!("AFastDeserialize does not support unions"),
724 };
725
726 TokenStream::from(expanded)
727}
728
729/// 为结构体的字段生成 `to_bytes()` 序列化代码。内部辅助函数。
730///
731/// Generates `to_bytes()` serialization code for struct fields. Internal helper.
732///
733/// 跳过所有标记了 `#[afast(skip)]` 的字段。
734///
735/// Skips all fields marked with `#[afast(skip)]`.
736///
737/// # 参数 / Parameters
738///
739/// - `fields`:结构体的字段定义 / The struct's field definitions
740/// - `self_prefix`:访问字段时使用的前缀(如 `self` 或变体解构变量)
741/// / The prefix used to access fields (e.g., `self` or a variant destructure variable)
742///
743/// # 返回值 / Returns
744///
745/// 返回一个 `TokenStream` 列表,每个元素对应一个字段的序列化语句。
746///
747/// Returns a list of `TokenStream`s, each corresponding to a serialization statement
748/// for one field.
749///
750/// # 生成格式 / Generated Format
751///
752/// - **命名字段 (Named)**:`__afast_bytes__.extend(AFastSerialize::to_bytes(&self.field_name));`
753/// - **元组字段 (Unnamed)**:`__afast_bytes__.extend(AFastSerialize::to_bytes(&self.0));`
754/// - **单元字段 (Unit)**:不生成任何代码 / Generates no code
755fn generate_serialize_fields(
756 fields: &Fields,
757 self_prefix: proc_macro2::TokenStream,
758) -> Vec<proc_macro2::TokenStream> {
759 match fields {
760 Fields::Named(named) => named
761 .named
762 .iter()
763 .filter(|f| !has_skip_attr(&f.attrs).0)
764 .map(|f| {
765 let fname = f.ident.as_ref().unwrap();
766 quote! {
767 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes(&#self_prefix.#fname));
768 }
769 })
770 .collect(),
771 Fields::Unnamed(unnamed) => unnamed
772 .unnamed
773 .iter()
774 .enumerate()
775 .filter(|(_, f)| !has_skip_attr(&f.attrs).0)
776 .map(|(i, _)| {
777 let idx = Index::from(i);
778 quote! {
779 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes(&#self_prefix.#idx));
780 }
781 })
782 .collect(),
783 Fields::Unit => vec![],
784 }
785}
786
787/// 为结构体的字段生成带 marker 的序列化代码。内部辅助函数。
788///
789/// Generates marker-aware serialization code for struct fields. Internal helper.
790///
791/// 跳过 `#[afast(skip)]` 字段,marker 匹配的 `#[afast(skip_with(...))]` 字段在运行时跳过。
792///
793/// Skips `#[afast(skip)]` fields unconditionally. `#[afast(skip_with(...))]` fields
794/// whose marker matches are skipped at runtime.
795fn generate_serialize_fields_with(
796 fields: &Fields,
797 self_prefix: proc_macro2::TokenStream,
798 marker: &proc_macro2::Ident,
799) -> Vec<proc_macro2::TokenStream> {
800 match fields {
801 Fields::Named(named) => {
802 let mut stmts = Vec::new();
803 for f in &named.named {
804 if has_skip_attr(&f.attrs).0 {
805 continue;
806 }
807 let fname = f.ident.as_ref().unwrap();
808 let skip_with = has_skip_with_attr(&f.attrs);
809 if let Some((m, _)) = skip_with {
810 stmts.push(quote! {
811 if #m != #marker {
812 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(&#self_prefix.#fname, #marker));
813 }
814 });
815 } else {
816 stmts.push(quote! {
817 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(&#self_prefix.#fname, #marker));
818 });
819 }
820 }
821 stmts
822 }
823 Fields::Unnamed(unnamed) => {
824 let mut stmts = Vec::new();
825 for (i, f) in unnamed.unnamed.iter().enumerate() {
826 if has_skip_attr(&f.attrs).0 {
827 continue;
828 }
829 let idx = Index::from(i);
830 let skip_with = has_skip_with_attr(&f.attrs);
831 if let Some((m, _)) = skip_with {
832 stmts.push(quote! {
833 if #m != #marker {
834 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(&#self_prefix.#idx, #marker));
835 }
836 });
837 } else {
838 stmts.push(quote! {
839 __afast_bytes__.extend(::afastdata::AFastSerialize::to_bytes_with(&#self_prefix.#idx, #marker));
840 });
841 }
842 }
843 stmts
844 }
845 Fields::Unit => vec![],
846 }
847}
848
849/// 检查字段是否有 `#[afast(skip)]` 或 `#[afast(skip("fn_name"))]` 属性。
850///
851/// Checks whether a field has `#[afast(skip)]` or `#[afast(skip("fn_name"))]` attribute.
852///
853/// 返回值 / Returns:
854/// - `(true, None)`:`#[afast(skip)]`,反序列化用 `Default` / uses `Default` for deserialization
855/// - `(true, Some("fn"))`:`#[afast(skip("fn"))]`,反序列化用指定函数 / uses specified function
856/// - `(false, None)`:无 skip 属性 / no skip attribute
857fn has_skip_attr(attrs: &[Attribute]) -> (bool, Option<String>) {
858 for attr in attrs {
859 if attr.path().is_ident("afast")
860 && let Ok(nested) =
861 attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
862 {
863 for meta in nested {
864 match meta {
865 Meta::Path(path) if path.is_ident("skip") => {
866 return (true, None);
867 }
868 Meta::List(meta_list) if meta_list.path.is_ident("skip") => {
869 if let Ok(lit_str) = syn::parse2::<LitStr>(meta_list.tokens.clone()) {
870 return (true, Some(lit_str.value()));
871 } else {
872 return (true, None);
873 }
874 }
875 _ => {}
876 }
877 }
878 }
879 }
880 (false, None)
881}
882
883/// 检查字段是否有 `#[afast(skip_with("marker"))]` 或
884/// `#[afast(skip_with("marker", "default_fn"))]` 属性。
885///
886/// Checks whether a field has `#[afast(skip_with("marker"))]` or
887/// `#[afast(skip_with("marker", "default_fn"))]` attribute.
888///
889/// 返回值:`(marker, default_fn)`
890/// - `Some(("marker", None))`:`#[afast(skip_with("marker"))]`,反序列化用 Default
891/// - `Some(("marker", Some("fn")))`:`#[afast(skip_with("marker", "fn"))]`
892/// - `None`:无 skip_with 属性
893fn has_skip_with_attr(attrs: &[Attribute]) -> Option<(String, Option<String>)> {
894 for attr in attrs {
895 if attr.path().is_ident("afast")
896 && let Ok(nested) =
897 attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
898 {
899 for meta in nested {
900 if let Meta::List(meta_list) = meta
901 && meta_list.path.is_ident("skip_with")
902 {
903 let tokens = meta_list.tokens.clone();
904 if let Ok(args) = syn::parse2::<SkipWithArgs>(tokens) {
905 return Some((args.marker.value(), args.default_fn.map(|s| s.value())));
906 }
907 return None;
908 }
909 }
910 }
911 }
912 None
913}
914
915/// `#[afast(skip_with(...))]` 属性的解析结果。
916///
917/// Parsed representation of the `#[afast(skip_with(...))]` attribute.
918///
919/// - `marker`:用于匹配的标记字符串 / The marker string used for matching
920/// - `default_fn`:可选的默认值生成函数名 / Optional function name for generating default values
921struct SkipWithArgs {
922 marker: LitStr,
923 default_fn: Option<LitStr>,
924}
925
926impl Parse for SkipWithArgs {
927 /// 解析 `"marker"` 或 `"marker", "default_fn"` 格式的参数。
928 ///
929 /// Parses arguments in the format `"marker"` or `"marker", "default_fn"`.
930 fn parse(input: ParseStream) -> syn::Result<Self> {
931 let marker: LitStr = input.parse()?;
932 let default_fn = if input.peek(Token![,]) {
933 input.parse::<Token![,]>()?;
934 Some(input.parse::<LitStr>()?)
935 } else {
936 None
937 };
938 Ok(SkipWithArgs { marker, default_fn })
939 }
940}
941
942/// 范围校验中使用的值,支持整数和浮点数。
943///
944/// A value used in range validation, supporting both integers and floats.
945enum RangeValue {
946 /// 整数字面量 / Integer literal
947 Int(LitInt),
948 /// 浮点字面量 / Float literal
949 Float(LitFloat),
950}
951
952impl RangeValue {
953 /// 将值转换为可用于代码生成的 `TokenStream`。
954 ///
955 /// Converts the value into a `TokenStream` for code generation.
956 fn to_token_stream(&self) -> proc_macro2::TokenStream {
957 match self {
958 RangeValue::Int(v) => quote! { #v },
959 RangeValue::Float(v) => quote! { #v },
960 }
961 }
962}
963
964/// `gt`/`gte`/`lt`/`lte` 范围校验的参数。
965///
966/// Parameters for `gt`/`gte`/`lt`/`lte` range validation.
967///
968/// 格式:`(比较值, 错误码, "错误消息")`
969///
970/// Format: `(comparison_value, error_code, "error message")`
971struct Range {
972 /// 要比较的阈值 / The threshold value to compare against
973 value: RangeValue,
974 _comma1: Token![,],
975 /// 验证失败时的错误码 / Error code when validation fails
976 code: LitInt,
977 _comma2: Token![,],
978 /// 验证失败时的错误消息 / Error message when validation fails
979 msg: LitStr,
980}
981
982impl Parse for Range {
983 /// 解析 `(value, code, "msg")` 格式的参数,自动识别整数或浮点值。
984 ///
985 /// Parses arguments in `(value, code, "msg")` format, automatically detecting
986 /// integer or float values.
987 fn parse(input: ParseStream) -> syn::Result<Self> {
988 // 优先尝试解析为浮点数,再尝试整数
989 // Try to parse as float first, then as int
990 let value = if input.peek(LitFloat) {
991 RangeValue::Float(input.parse()?)
992 } else {
993 RangeValue::Int(input.parse()?)
994 };
995 Ok(Range {
996 value,
997 _comma1: input.parse()?,
998 code: input.parse()?,
999 _comma2: input.parse()?,
1000 msg: input.parse()?,
1001 })
1002 }
1003}
1004
1005/// `len` 长度校验的参数。
1006///
1007/// Parameters for `len` length validation.
1008///
1009/// 格式:`(min, max, 错误码, "错误消息")`
1010///
1011/// Format: `(min, max, error_code, "error message")`
1012struct Length {
1013 /// 最小长度(含)/ Minimum length (inclusive)
1014 min: LitInt,
1015 _comma1: Token![,],
1016 /// 最大长度(含)/ Maximum length (inclusive)
1017 max: LitInt,
1018 _comma2: Token![,],
1019 /// 验证失败时的错误码 / Error code when validation fails
1020 code: LitInt,
1021 _comma3: Token![,],
1022 /// 验证失败时的错误消息 / Error message when validation fails
1023 msg: LitStr,
1024}
1025
1026impl Parse for Length {
1027 /// 解析 `(min, max, code, "msg")` 格式的参数。
1028 ///
1029 /// Parses arguments in `(min, max, code, "msg")` format.
1030 fn parse(input: ParseStream) -> syn::Result<Self> {
1031 Ok(Length {
1032 min: input.parse()?,
1033 _comma1: input.parse()?,
1034 max: input.parse()?,
1035 _comma2: input.parse()?,
1036 code: input.parse()?,
1037 _comma3: input.parse()?,
1038 msg: input.parse()?,
1039 })
1040 }
1041}
1042
1043/// `of` 校验中允许的值,支持多种字面量类型。
1044///
1045/// An allowed value in `of` validation, supporting multiple literal types.
1046#[derive(Clone)]
1047enum ValidateValue {
1048 /// 整数值 / Integer value
1049 Int(i64),
1050 /// 浮点值 / Float value
1051 Float(f64),
1052 /// 布尔值 / Boolean value
1053 Bool(bool),
1054 /// 字符串值 / String value
1055 Str(String),
1056}
1057
1058impl ValidateValue {
1059 /// 将值转换为代码生成中使用的 TokenStream。
1060 ///
1061 /// Converts the value into a `TokenStream` for code generation.
1062 ///
1063 /// 例如 / Example:
1064 /// - `ValidateValue::Int(42)` → `quote! { 42 }`
1065 /// - `ValidateValue::Str("hello")` → `quote! { "hello" }`
1066 fn to_token_stream(&self) -> proc_macro2::TokenStream {
1067 match self {
1068 ValidateValue::Int(v) => quote! { #v },
1069
1070 ValidateValue::Float(v) => {
1071 // 浮点数通过字符串解析来保持精度
1072 let v_str = v.to_string();
1073 v_str.parse().unwrap_or_else(|_| {
1074 // 如果字符串解析失败,使用直接值
1075 quote! { #v }
1076 })
1077 }
1078
1079 ValidateValue::Bool(v) => quote! { #v },
1080 ValidateValue::Str(v) => quote! { #v },
1081 }
1082 }
1083}
1084
1085/// `of` 枚举值校验的参数。
1086///
1087/// Parameters for `of` enum-value validation.
1088///
1089/// 格式:`([值1, 值2, ...], 错误码, "错误消息")`
1090///
1091/// Format: `([val1, val2, ...], error_code, "error message")`
1092struct OfValidator {
1093 /// 允许的值列表 / List of allowed values
1094 allowed_values: Vec<ValidateValue>,
1095 /// 验证失败时的错误码 / Error code when validation fails
1096 code: syn::LitInt,
1097 /// 验证失败时的错误消息 / Error message when validation fails
1098 msg: syn::LitStr,
1099}
1100
1101impl Parse for OfValidator {
1102 /// 解析 `([val1, val2, ...], code, "msg")` 格式的参数。
1103 ///
1104 /// Parses arguments in `([val1, val2, ...], code, "msg")` format.
1105 fn parse(input: ParseStream) -> syn::Result<Self> {
1106 let content;
1107 syn::bracketed!(content in input);
1108
1109 let mut values = Vec::new();
1110
1111 if !content.is_empty() {
1112 loop {
1113 let lit = content.parse::<Lit>()?;
1114
1115 let value = match lit {
1116 Lit::Int(lit_int) => {
1117 let int_value: i64 = lit_int.base10_parse()?;
1118 ValidateValue::Int(int_value)
1119 }
1120
1121 Lit::Float(lit_float) => {
1122 let float_value: f64 = lit_float.base10_parse()?;
1123 ValidateValue::Float(float_value)
1124 }
1125
1126 Lit::Bool(lit_bool) => ValidateValue::Bool(lit_bool.value),
1127
1128 Lit::Str(lit_str) => ValidateValue::Str(lit_str.value()),
1129
1130 _ => {
1131 return Err(syn::Error::new_spanned(
1132 &lit,
1133 "unsupported literal type in 'of' validator; \
1134 only int, float, bool, and str literals are supported",
1135 ));
1136 }
1137 };
1138
1139 values.push(value);
1140
1141 if !content.peek(Token![,]) {
1142 break;
1143 }
1144
1145 content.parse::<Token![,]>()?;
1146
1147 if content.is_empty() {
1148 break;
1149 }
1150 }
1151 }
1152
1153 input.parse::<Token![,]>()?;
1154
1155 let code = input.parse::<syn::LitInt>()?;
1156
1157 input.parse::<Token![,]>()?;
1158
1159 let msg = input.parse::<syn::LitStr>()?;
1160
1161 Ok(OfValidator {
1162 allowed_values: values,
1163 code,
1164 msg,
1165 })
1166 }
1167}
1168
1169/// 检测字段类型是否为数值类型(i8..i128, u8..u128, f32, f64)。
1170///
1171/// Checks whether the field type is a numeric type.
1172fn is_numeric_type(ty: &Type) -> bool {
1173 if let Type::Path(TypePath { path, .. }) = ty
1174 && let Some(segment) = path.segments.last()
1175 {
1176 let name = segment.ident.to_string();
1177 return matches!(
1178 name.as_str(),
1179 "i8" | "i16"
1180 | "i32"
1181 | "i64"
1182 | "i128"
1183 | "u8"
1184 | "u16"
1185 | "u32"
1186 | "u64"
1187 | "u128"
1188 | "usize"
1189 | "f32"
1190 | "f64"
1191 );
1192 }
1193 false
1194}
1195
1196/// 检测字段类型是否为 Option<T>。
1197///
1198/// Checks whether the field type is `Option<T>`.
1199fn is_option_type(ty: &Type) -> bool {
1200 if let Type::Path(TypePath {
1201 path: Path { segments, .. },
1202 ..
1203 }) = ty
1204 {
1205 segments.len() == 1 && segments[0].ident == "Option"
1206 } else {
1207 false
1208 }
1209}
1210
1211/// 提取 Option<T> 的内部类型 T。
1212///
1213/// Extracts the inner type `T` from `Option<T>`.
1214fn extract_option_inner(ty: &Type) -> Option<&Type> {
1215 if let Type::Path(TypePath {
1216 path: Path { segments, .. },
1217 ..
1218 }) = ty
1219 && segments.len() == 1
1220 && segments[0].ident == "Option"
1221 && let syn::PathArguments::AngleBracketed(args) = &segments[0].arguments
1222 && let Some(syn::GenericArgument::Type(inner)) = args.args.first()
1223 {
1224 return Some(inner);
1225 }
1226 None
1227}
1228
1229/// 检测字段类型是否为可进行比较校验的类型(数值类型或 Option<数值类型>)。
1230///
1231/// Checks whether the field type supports comparison validation
1232/// (numeric type or Option<numeric type>).
1233fn is_comparable_type(ty: &Type) -> bool {
1234 if is_numeric_type(ty) {
1235 return true;
1236 }
1237 if let Some(inner) = extract_option_inner(ty) {
1238 return is_numeric_type(inner);
1239 }
1240 false
1241}
1242
1243/// 检测字段类型是否为字符串或集合类型(String, &str, Vec<T>, [T; N])。
1244///
1245/// Checks whether the field type is a string or collection type.
1246fn is_collection_type(ty: &Type) -> bool {
1247 if let Type::Path(TypePath { path, .. }) = ty
1248 && let Some(segment) = path.segments.last()
1249 {
1250 let name = segment.ident.to_string();
1251 return matches!(
1252 name.as_str(),
1253 "String" | "Vec" | "BTreeSet" | "BTreeMap" | "HashSet" | "HashMap"
1254 );
1255 }
1256 // [T; N] arrays
1257 if let Type::Array(_) = ty {
1258 return true;
1259 }
1260 // &str
1261 if let Type::Reference(r) = ty
1262 && let Type::Path(TypePath { path, .. }) = &*r.elem
1263 && let Some(segment) = path.segments.last()
1264 {
1265 return segment.ident == "str";
1266 }
1267 false
1268}
1269
1270/// 解析字段上的 `#[afast(...)]` 校验属性,生成校验代码。
1271///
1272/// Parses `#[afast(...)]` validation attributes on a field and generates
1273/// validation code blocks.
1274///
1275/// # 参数 / Parameters
1276///
1277/// - `field_name`:字段名 / Field name
1278/// - `field_type`:字段类型 / Field type
1279/// - `attrs`:字段的属性列表 / Field attributes
1280///
1281/// # 返回值 / Returns
1282///
1283/// 返回校验语句的 `TokenStream` 列表。
1284///
1285/// Returns a list of validation `TokenStream` blocks.
1286fn parse_validations(
1287 field_name: &syn::Ident,
1288 field_type: &Type,
1289 attrs: &[Attribute],
1290) -> Vec<proc_macro2::TokenStream> {
1291 let mut validates = Vec::new();
1292 for attr in attrs {
1293 if attr.path().is_ident("afast") {
1294 let nested = match attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
1295 {
1296 Ok(n) => n,
1297 Err(e) => {
1298 validates.push(e.to_compile_error());
1299 continue;
1300 }
1301 };
1302 for meta in nested {
1303 if let Meta::List(meta) = meta {
1304 if meta.path.is_ident("gt") {
1305 if !is_comparable_type(field_type) {
1306 validates.push(
1307 syn::Error::new_spanned(
1308 &meta.path,
1309 format!(
1310 "validation `gt` is only supported on numeric types or Option<numeric>, but field `{}` is not",
1311 field_name
1312 ),
1313 )
1314 .to_compile_error(),
1315 );
1316 continue;
1317 }
1318 let inner = match meta.parse_args::<Range>() {
1319 Ok(v) => v,
1320 Err(e) => {
1321 validates.push(e.to_compile_error());
1322 continue;
1323 }
1324 };
1325 let cmp_value = inner.value.to_token_stream();
1326 let code = match inner.code.base10_parse::<i64>() {
1327 Ok(v) => v,
1328 Err(e) => {
1329 validates.push(
1330 syn::Error::new_spanned(
1331 &inner.code,
1332 format!("invalid error code: {}", e),
1333 )
1334 .to_compile_error(),
1335 );
1336 continue;
1337 }
1338 };
1339 let err_msg = inner
1340 .msg
1341 .value()
1342 .replace("${field}", &field_name.to_string());
1343 if is_option_type(field_type) {
1344 validates.push(quote! {
1345 if let Some(ref __val) = #field_name {
1346 if *__val <= #cmp_value {
1347 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1348 }
1349 }
1350 });
1351 } else {
1352 validates.push(quote! {
1353 if #field_name <= #cmp_value {
1354 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1355 }
1356 });
1357 }
1358 } else if meta.path.is_ident("gte") {
1359 if !is_comparable_type(field_type) {
1360 validates.push(
1361 syn::Error::new_spanned(
1362 &meta.path,
1363 format!(
1364 "validation `gte` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
1365 field_name
1366 ),
1367 )
1368 .to_compile_error(),
1369 );
1370 continue;
1371 }
1372 let inner = match meta.parse_args::<Range>() {
1373 Ok(v) => v,
1374 Err(e) => {
1375 validates.push(e.to_compile_error());
1376 continue;
1377 }
1378 };
1379 let cmp_value = inner.value.to_token_stream();
1380 let code = match inner.code.base10_parse::<i64>() {
1381 Ok(v) => v,
1382 Err(e) => {
1383 validates.push(
1384 syn::Error::new_spanned(
1385 &inner.code,
1386 format!("invalid error code: {}", e),
1387 )
1388 .to_compile_error(),
1389 );
1390 continue;
1391 }
1392 };
1393 let err_msg = inner
1394 .msg
1395 .value()
1396 .replace("${field}", &field_name.to_string());
1397 if is_option_type(field_type) {
1398 validates.push(quote! {
1399 if let Some(ref __val) = #field_name {
1400 if *__val < #cmp_value {
1401 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1402 }
1403 }
1404 });
1405 } else {
1406 validates.push(quote! {
1407 if #field_name < #cmp_value {
1408 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1409 }
1410 });
1411 }
1412 } else if meta.path.is_ident("lt") {
1413 if !is_comparable_type(field_type) {
1414 validates.push(
1415 syn::Error::new_spanned(
1416 &meta.path,
1417 format!(
1418 "validation `lt` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
1419 field_name
1420 ),
1421 )
1422 .to_compile_error(),
1423 );
1424 continue;
1425 }
1426 let inner = match meta.parse_args::<Range>() {
1427 Ok(v) => v,
1428 Err(e) => {
1429 validates.push(e.to_compile_error());
1430 continue;
1431 }
1432 };
1433 let cmp_value = inner.value.to_token_stream();
1434 let code = match inner.code.base10_parse::<i64>() {
1435 Ok(v) => v,
1436 Err(e) => {
1437 validates.push(
1438 syn::Error::new_spanned(
1439 &inner.code,
1440 format!("invalid error code: {}", e),
1441 )
1442 .to_compile_error(),
1443 );
1444 continue;
1445 }
1446 };
1447 let err_msg = inner
1448 .msg
1449 .value()
1450 .replace("${field}", &field_name.to_string());
1451 if is_option_type(field_type) {
1452 validates.push(quote! {
1453 if let Some(ref __val) = #field_name {
1454 if *__val >= #cmp_value {
1455 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1456 }
1457 }
1458 });
1459 } else {
1460 validates.push(quote! {
1461 if #field_name >= #cmp_value {
1462 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1463 }
1464 });
1465 }
1466 } else if meta.path.is_ident("lte") {
1467 if !is_comparable_type(field_type) {
1468 validates.push(
1469 syn::Error::new_spanned(
1470 &meta.path,
1471 format!(
1472 "validation `lte` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
1473 field_name
1474 ),
1475 )
1476 .to_compile_error(),
1477 );
1478 continue;
1479 }
1480 let inner = match meta.parse_args::<Range>() {
1481 Ok(v) => v,
1482 Err(e) => {
1483 validates.push(e.to_compile_error());
1484 continue;
1485 }
1486 };
1487 let cmp_value = inner.value.to_token_stream();
1488 let code = match inner.code.base10_parse::<i64>() {
1489 Ok(v) => v,
1490 Err(e) => {
1491 validates.push(
1492 syn::Error::new_spanned(
1493 &inner.code,
1494 format!("invalid error code: {}", e),
1495 )
1496 .to_compile_error(),
1497 );
1498 continue;
1499 }
1500 };
1501 let err_msg = inner
1502 .msg
1503 .value()
1504 .replace("${field}", &field_name.to_string());
1505 if is_option_type(field_type) {
1506 validates.push(quote! {
1507 if let Some(ref __val) = #field_name {
1508 if *__val > #cmp_value {
1509 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1510 }
1511 }
1512 });
1513 } else {
1514 validates.push(quote! {
1515 if #field_name > #cmp_value {
1516 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1517 }
1518 });
1519 }
1520 } else if meta.path.is_ident("len") {
1521 let field_is_option = is_option_type(field_type);
1522 // For Option<T>, check if inner type is a collection
1523 // For non-Option, check directly
1524 if field_is_option {
1525 // Option<T> is allowed - inner type check is deferred to runtime
1526 } else if !is_collection_type(field_type) {
1527 validates.push(
1528 syn::Error::new_spanned(
1529 &meta.path,
1530 format!(
1531 "validation `len` is only supported on String, &[u8], Vec<T>, [T; N], or Option<T> wrapping these types, but field `{}` is not",
1532 field_name
1533 ),
1534 )
1535 .to_compile_error(),
1536 );
1537 continue;
1538 }
1539
1540 let inner = match meta.parse_args::<Length>() {
1541 Ok(v) => v,
1542 Err(e) => {
1543 validates.push(e.to_compile_error());
1544 continue;
1545 }
1546 };
1547 let min_value = match inner.min.base10_parse::<i64>() {
1548 Ok(v) => v,
1549 Err(e) => {
1550 validates.push(
1551 syn::Error::new_spanned(
1552 &inner.min,
1553 format!("invalid min value: {}", e),
1554 )
1555 .to_compile_error(),
1556 );
1557 continue;
1558 }
1559 };
1560 let max_value = match inner.max.base10_parse::<i64>() {
1561 Ok(v) => v,
1562 Err(e) => {
1563 validates.push(
1564 syn::Error::new_spanned(
1565 &inner.max,
1566 format!("invalid max value: {}", e),
1567 )
1568 .to_compile_error(),
1569 );
1570 continue;
1571 }
1572 };
1573 let code = match inner.code.base10_parse::<i64>() {
1574 Ok(v) => v,
1575 Err(e) => {
1576 validates.push(
1577 syn::Error::new_spanned(
1578 &inner.code,
1579 format!("invalid error code: {}", e),
1580 )
1581 .to_compile_error(),
1582 );
1583 continue;
1584 }
1585 };
1586 let err_msg = inner
1587 .msg
1588 .value()
1589 .replace("${field}", &field_name.to_string());
1590 // -1 is a sentinel meaning "no limit", so skip range check when either is -1
1591 if min_value >= 0 && max_value >= 0 && min_value > max_value {
1592 validates.push(
1593 syn::Error::new_spanned(
1594 &meta.path,
1595 format!(
1596 "invalid len validation: min ({}) > max ({}) for field `{}`",
1597 min_value, max_value, field_name
1598 ),
1599 )
1600 .to_compile_error(),
1601 );
1602 continue;
1603 }
1604 if min_value < 0 && max_value < 0 {
1605 validates.push(
1606 syn::Error::new_spanned(
1607 &meta.path,
1608 format!(
1609 "invalid len validation: both min and max are negative for field `{}`",
1610 field_name
1611 ),
1612 )
1613 .to_compile_error(),
1614 );
1615 continue;
1616 } else if min_value < 0 {
1617 let max: usize = match max_value.try_into() {
1618 Ok(v) => v,
1619 Err(_) => {
1620 validates.push(
1621 syn::Error::new_spanned(
1622 &inner.max,
1623 "value too large for usize",
1624 )
1625 .to_compile_error(),
1626 );
1627 continue;
1628 }
1629 };
1630 if field_is_option {
1631 validates.push(quote! {
1632 if let Some(ref __val) = #field_name {
1633 if __val.len() > #max {
1634 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1635 }
1636 }
1637 });
1638 } else {
1639 validates.push(quote! {
1640 if #field_name.len() > #max {
1641 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1642 }
1643 });
1644 }
1645 } else if max_value < 0 {
1646 let min: usize = match min_value.try_into() {
1647 Ok(v) => v,
1648 Err(_) => {
1649 validates.push(
1650 syn::Error::new_spanned(
1651 &inner.min,
1652 "value too large for usize",
1653 )
1654 .to_compile_error(),
1655 );
1656 continue;
1657 }
1658 };
1659 if field_is_option {
1660 validates.push(quote! {
1661 if let Some(ref __val) = #field_name {
1662 if __val.len() < #min {
1663 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1664 }
1665 }
1666 });
1667 } else {
1668 validates.push(quote! {
1669 if #field_name.len() < #min {
1670 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1671 }
1672 });
1673 }
1674 } else {
1675 let min: usize = match min_value.try_into() {
1676 Ok(v) => v,
1677 Err(_) => {
1678 validates.push(
1679 syn::Error::new_spanned(
1680 &inner.min,
1681 "value too large for usize",
1682 )
1683 .to_compile_error(),
1684 );
1685 continue;
1686 }
1687 };
1688 let max: usize = match max_value.try_into() {
1689 Ok(v) => v,
1690 Err(_) => {
1691 validates.push(
1692 syn::Error::new_spanned(
1693 &inner.max,
1694 "value too large for usize",
1695 )
1696 .to_compile_error(),
1697 );
1698 continue;
1699 }
1700 };
1701 if field_is_option {
1702 validates.push(quote! {
1703 if let Some(ref __val) = #field_name {
1704 if !(#min..=#max).contains(&__val.len()) {
1705 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1706 }
1707 }
1708 });
1709 } else {
1710 validates.push(quote! {
1711 if !(#min..=#max).contains(&#field_name.len()) {
1712 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1713 }
1714 });
1715 }
1716 }
1717 } else if meta.path.is_ident("of") {
1718 let inner = match meta.parse_args::<OfValidator>() {
1719 Ok(v) => v,
1720 Err(e) => {
1721 validates.push(e.to_compile_error());
1722 continue;
1723 }
1724 };
1725 let allowed_values = inner.allowed_values.clone();
1726 let code = match inner.code.base10_parse::<i64>() {
1727 Ok(v) => v,
1728 Err(e) => {
1729 validates.push(
1730 syn::Error::new_spanned(
1731 &inner.code,
1732 format!("invalid error code: {}", e),
1733 )
1734 .to_compile_error(),
1735 );
1736 continue;
1737 }
1738 };
1739 let err_msg = inner
1740 .msg
1741 .value()
1742 .replace("${field}", &field_name.to_string());
1743 let values_tokens: Vec<_> =
1744 allowed_values.iter().map(|v| v.to_token_stream()).collect();
1745 validates.push(quote! {
1746 if !matches!(#field_name, #(#values_tokens)|*) {
1747 return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1748 }
1749 });
1750 } else if meta.path.is_ident("func") {
1751 let inner = match meta.parse_args::<LitStr>() {
1752 Ok(v) => v,
1753 Err(e) => {
1754 validates.push(e.to_compile_error());
1755 continue;
1756 }
1757 };
1758 let ident = match syn::parse_str::<syn::Ident>(&inner.value()) {
1759 Ok(v) => v,
1760 Err(e) => {
1761 validates.push(
1762 syn::Error::new_spanned(
1763 &inner,
1764 format!("invalid function name `{}`: {}", inner.value(), e),
1765 )
1766 .to_compile_error(),
1767 );
1768 continue;
1769 }
1770 };
1771 let field = field_name.to_string();
1772 validates.push(quote! {
1773 match #ident(&#field_name, #field) {
1774 Ok(()) => {},
1775 Err(e) => return Err(e.to_afastdata_error()),
1776 }
1777 });
1778 }
1779 }
1780 }
1781 }
1782 }
1783 validates
1784}
1785
1786/// 为结构体的字段生成反序列化代码以及构造表达式。内部辅助函数。
1787///
1788/// Generates deserialization code for struct fields along with the construction
1789/// expression. Internal helper.
1790///
1791/// # 参数 / Parameters
1792///
1793/// - `fields`:结构体的字段定义 / The struct's field definitions
1794/// - `name`:结构体类型的标识符 / The struct type's identifier
1795/// - `ty_generics`:类型的泛型参数(用于构造时的 turbofish 语法)
1796/// / The type's generic parameters (used for turbofish syntax during construction)
1797///
1798/// # 返回值 / Returns
1799///
1800/// 返回 `(构造表达式, 反序列化语句列表)`:
1801/// - 构造表达式:用于创建结构体实例的 `TokenStream`
1802/// - 反序列化语句:每个字段的 `from_bytes()` 调用和偏移量更新
1803///
1804/// Returns `(construction_expression, deserialization_statements)`:
1805/// - Construction expression: A `TokenStream` for creating the struct instance
1806/// - Deserialization statements: `from_bytes()` calls and offset updates for each field
1807///
1808/// # 泛型构造 / Generic Construction
1809///
1810/// 使用 `as_turbofish()` 生成正确的泛型语法。例如 `MyStruct::<T>` 而非
1811/// `MyStruct <T>`(后者会被解析为比较操作)。
1812///
1813/// Uses `as_turbofish()` to generate correct generic syntax. For example,
1814/// `MyStruct::<T>` instead of `MyStruct <T>` (which would be parsed as a
1815/// comparison operation).
1816fn generate_deserialize_fields(
1817 fields: &Fields,
1818 name: &syn::Ident,
1819 ty_generics: &syn::TypeGenerics,
1820) -> (proc_macro2::TokenStream, Vec<proc_macro2::TokenStream>) {
1821 // 在表达式上下文中使用 turbofish 语法:Name::<T>
1822 // In expression context, use turbofish syntax: Name::<T>
1823 let ty_params = ty_generics.as_turbofish();
1824 match fields {
1825 Fields::Named(named) => {
1826 let mut desers = Vec::new();
1827 let mut field_names = Vec::new();
1828 for f in &named.named {
1829 let fname = f.ident.as_ref().unwrap();
1830 let ftype = &f.ty;
1831 field_names.push(fname.clone());
1832
1833 let validates = parse_validations(fname, ftype, &f.attrs);
1834 let (skip, default) = has_skip_attr(&f.attrs);
1835 if skip {
1836 if let Some(default) = default {
1837 match syn::parse_str::<syn::Ident>(&default) {
1838 Ok(ident) => {
1839 desers.push(quote! {
1840 let #fname: #ftype = #ident();
1841 });
1842 }
1843 Err(_) => {
1844 desers.push(quote! {
1845 compile_error!(concat!("invalid function name in skip: ", #default));
1846 });
1847 }
1848 }
1849 } else {
1850 desers.push(quote! {
1851 let #fname: #ftype = #ftype::default();
1852 });
1853 }
1854 } else {
1855 desers.push(quote! {
1856 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&__afast_data__[__afast_offset__..])?;
1857 let #fname: #ftype = __val;
1858 #(#validates)*
1859 __afast_offset__ += __new_offset;
1860 });
1861 }
1862 }
1863 let construct = quote! {
1864 #name #ty_params { #(#field_names),* }
1865 };
1866 (construct, desers)
1867 }
1868 Fields::Unnamed(unnamed) => {
1869 let mut desers = Vec::new();
1870 let mut field_names = Vec::new();
1871 for (i, f) in unnamed.unnamed.iter().enumerate() {
1872 let fname = syn::Ident::new(&format!("__f{}", i), name.span());
1873 let ftype = &f.ty;
1874 let (skip, default_fn) = has_skip_attr(&f.attrs);
1875 if skip {
1876 if let Some(func_name) = default_fn {
1877 match syn::parse_str::<syn::Ident>(&func_name) {
1878 Ok(ident) => {
1879 desers.push(quote! {
1880 let #fname: #ftype = #ident();
1881 });
1882 }
1883 Err(_) => {
1884 desers.push(quote! {
1885 compile_error!(concat!("invalid function name in skip: ", #func_name));
1886 });
1887 }
1888 }
1889 } else {
1890 desers.push(quote! {
1891 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
1892 });
1893 }
1894 } else {
1895 let validates = parse_validations(&fname, ftype, &f.attrs);
1896 desers.push(quote! {
1897 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&__afast_data__[__afast_offset__..])?;
1898 let #fname: #ftype = __val;
1899 #(#validates)*
1900 __afast_offset__ += __new_offset;
1901 });
1902 }
1903 field_names.push(fname);
1904 }
1905 let construct = quote! {
1906 #name #ty_params ( #(#field_names),* )
1907 };
1908 (construct, desers)
1909 }
1910 Fields::Unit => {
1911 let construct = quote! { #name #ty_params };
1912 (construct, vec![])
1913 }
1914 }
1915}
1916
1917/// 为结构体的字段生成带 marker 的反序列化代码以及构造表达式。内部辅助函数。
1918///
1919/// Generates marker-aware deserialization code for struct fields along with the
1920/// construction expression. Internal helper.
1921///
1922/// marker 匹配的 `skip_with` 字段使用默认值或自定义函数填充,不从字节流读取。
1923///
1924/// `skip_with` fields whose marker matches are filled with default values or custom
1925/// functions, without reading from the byte stream.
1926fn generate_deserialize_fields_with(
1927 fields: &Fields,
1928 name: &syn::Ident,
1929 ty_generics: &syn::TypeGenerics,
1930 marker: &str,
1931) -> (proc_macro2::TokenStream, Vec<proc_macro2::TokenStream>) {
1932 let ty_params = ty_generics.as_turbofish();
1933 // marker 参数是生成代码中的参数名(如 "__afast_marker__"),不是实际值
1934 // The marker parameter is the parameter name in generated code, not the actual value
1935 let marker_ident = syn::Ident::new(marker, proc_macro2::Span::call_site());
1936 match fields {
1937 Fields::Named(named) => {
1938 let mut desers = Vec::new();
1939 let mut field_names = Vec::new();
1940 for f in &named.named {
1941 let fname = f.ident.as_ref().unwrap();
1942 let ftype = &f.ty;
1943 field_names.push(fname.clone());
1944
1945 let (skip, _) = has_skip_attr(&f.attrs);
1946 if skip {
1947 desers.push(quote! {
1948 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
1949 });
1950 } else {
1951 let skip_with = has_skip_with_attr(&f.attrs);
1952 if let Some((m, default_fn)) = skip_with {
1953 let default_expr = if let Some(fn_name) = default_fn {
1954 match syn::parse_str::<syn::Ident>(&fn_name) {
1955 Ok(ident) => quote! { #ident() },
1956 Err(_) => {
1957 quote! { { compile_error!(concat!("invalid function name in skip_with: ", #fn_name)); <#ftype as ::std::default::Default>::default() } }
1958 }
1959 }
1960 } else {
1961 quote! { <#ftype as ::std::default::Default>::default() }
1962 };
1963 let validates = parse_validations(fname, ftype, &f.attrs);
1964 desers.push(quote! {
1965 let #fname: #ftype = if #marker_ident == #m {
1966 #default_expr
1967 } else {
1968 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], #marker_ident)?;
1969 #(#validates)*
1970 __afast_offset__ += __new_offset;
1971 __val
1972 };
1973 });
1974 } else {
1975 let validates = parse_validations(fname, ftype, &f.attrs);
1976 desers.push(quote! {
1977 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], #marker_ident)?;
1978 let #fname: #ftype = __val;
1979 #(#validates)*
1980 __afast_offset__ += __new_offset;
1981 });
1982 }
1983 }
1984 }
1985 let construct = quote! {
1986 #name #ty_params { #(#field_names),* }
1987 };
1988 (construct, desers)
1989 }
1990 Fields::Unnamed(unnamed) => {
1991 let mut desers = Vec::new();
1992 let mut field_names = Vec::new();
1993 for (i, f) in unnamed.unnamed.iter().enumerate() {
1994 let fname = syn::Ident::new(&format!("__f{}", i), name.span());
1995 let ftype = &f.ty;
1996 field_names.push(fname.clone());
1997
1998 let (skip, _) = has_skip_attr(&f.attrs);
1999 if skip {
2000 desers.push(quote! {
2001 let #fname: #ftype = <#ftype as ::std::default::Default>::default();
2002 });
2003 } else {
2004 let skip_with = has_skip_with_attr(&f.attrs);
2005 if let Some((m, default_fn)) = skip_with {
2006 let default_expr = if let Some(fn_name) = default_fn {
2007 match syn::parse_str::<syn::Ident>(&fn_name) {
2008 Ok(ident) => quote! { #ident() },
2009 Err(_) => {
2010 quote! { { compile_error!(concat!("invalid function name in skip_with: ", #fn_name)); <#ftype as ::std::default::Default>::default() } }
2011 }
2012 }
2013 } else {
2014 quote! { <#ftype as ::std::default::Default>::default() }
2015 };
2016 let validates = parse_validations(&fname, ftype, &f.attrs);
2017 desers.push(quote! {
2018 let #fname: #ftype = if #marker_ident == #m {
2019 #default_expr
2020 } else {
2021 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], #marker_ident)?;
2022 #(#validates)*
2023 __afast_offset__ += __new_offset;
2024 __val
2025 };
2026 });
2027 } else {
2028 let validates = parse_validations(&fname, ftype, &f.attrs);
2029 desers.push(quote! {
2030 let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes_with(&__afast_data__[__afast_offset__..], #marker_ident)?;
2031 let #fname: #ftype = __val;
2032 #(#validates)*
2033 __afast_offset__ += __new_offset;
2034 });
2035 }
2036 }
2037 }
2038 let construct = quote! {
2039 #name #ty_params ( #(#field_names),* )
2040 };
2041 (construct, desers)
2042 }
2043 Fields::Unit => {
2044 let construct = quote! { #name #ty_params };
2045 (construct, vec![])
2046 }
2047 }
2048}