Skip to main content

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)**:写入 `u32` 变体索引 + 变体字段数据
19//!   / Writes a `u32` variant index + variant field data
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 | `u32` little-endian | 从 0 开始递增 / Starts from 0, incrementing |
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, Type,
78    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            quote! {
188                impl #impl_generics ::afastdata::AFastSerialize for #name #ty_generics {
189                    fn to_bytes(&self) -> Vec<u8> {
190                        let mut bytes = Vec::new();
191                        #(#serialize_body)*
192                        bytes
193                    }
194                }
195            }
196        }
197        Data::Enum(data) => {
198            let (tag_ty, _) = tag_type();
199            let mut arms = Vec::new();
200            for (i, variant) in data.variants.iter().enumerate() {
201                let variant_name = &variant.ident;
202
203                match &variant.fields {
204                    Fields::Unit => {
205                        arms.push(quote! {
206                            #name::#variant_name => {
207                                bytes.extend((#i as #tag_ty).to_le_bytes());
208                            }
209                        });
210                    }
211                    Fields::Unnamed(fields) => {
212                        let field_names: Vec<_> = (0..fields.unnamed.len())
213                            .map(|i| {
214                                syn::Ident::new(&format!("__f{}", i), variant_name.span())
215                            })
216                            .collect();
217                        let field_patterns = &field_names;
218                        let mut serialize_fields = Vec::new();
219                        for (i, f) in fields.unnamed.iter().enumerate() {
220                            if !has_skip_attr(&f.attrs).0 {
221                                let fname = &field_names[i];
222                                serialize_fields.push(quote! {
223                                    bytes.extend(::afastdata::AFastSerialize::to_bytes(#fname));
224                                });
225                            }
226                        }
227                        arms.push(quote! {
228                            #name::#variant_name(#(#field_patterns),*) => {
229                                bytes.extend((#i as #tag_ty).to_le_bytes());
230                                #(#serialize_fields)*
231                            }
232                        });
233                    }
234                    Fields::Named(fields) => {
235                        let all_field_names: Vec<_> = fields
236                            .named
237                            .iter()
238                            .map(|f| f.ident.as_ref().unwrap())
239                            .collect();
240                        let non_skip_names: Vec<_> = fields
241                            .named
242                            .iter()
243                            .filter(|f| !has_skip_attr(&f.attrs).0)
244                            .map(|f| f.ident.as_ref().unwrap())
245                            .collect();
246                        let has_skip = non_skip_names.len() < all_field_names.len();
247                        let mut serialize_fields = Vec::new();
248                        for fname in &non_skip_names {
249                            serialize_fields.push(quote! {
250                                bytes.extend(::afastdata::AFastSerialize::to_bytes(#fname));
251                            });
252                        }
253                        if has_skip {
254                            arms.push(quote! {
255                                #name::#variant_name { #(#non_skip_names),*, .. } => {
256                                    bytes.extend((#i as #tag_ty).to_le_bytes());
257                                    #(#serialize_fields)*
258                                }
259                            });
260                        } else {
261                            arms.push(quote! {
262                                #name::#variant_name { #(#non_skip_names),* } => {
263                                    bytes.extend((#i as #tag_ty).to_le_bytes());
264                                    #(#serialize_fields)*
265                                }
266                            });
267                        }
268                    }
269                }
270            }
271
272            quote! {
273                impl #impl_generics ::afastdata::AFastSerialize for #name #ty_generics {
274                    fn to_bytes(&self) -> Vec<u8> {
275                        let mut bytes = Vec::new();
276                        match self {
277                            #(#arms)*
278                        }
279                        bytes
280                    }
281                }
282            }
283        }
284        Data::Union(_) => panic!("AFastSerialize does not support unions"),
285    };
286
287    TokenStream::from(expanded)
288}
289
290/// 为结构体或枚举生成 [`AFastDeserialize`] trait 实现。
291///
292/// Generates an [`AFastDeserialize`] trait implementation for a struct or enum.
293///
294/// # 生成的代码 / Generated Code
295///
296/// ## 结构体 / Struct
297///
298/// 为每个字段依次调用 `from_bytes()`,并使用偏移量追踪已消耗的字节数,
299/// 最后构造结构体实例。
300///
301/// Calls `from_bytes()` on each field sequentially, using an offset to track
302/// consumed bytes, then constructs the struct instance.
303///
304/// ```text
305/// // 以下为生成代码的示意(非实际代码)
306/// // The following is an illustration of generated code (not actual code)
307/// impl AFastDeserialize for MyStruct {
308///     fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
309///         let mut offset: usize = 0;
310///         let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
311///         let field1 = __val;
312///         offset += __new_offset;
313///         // ... 更多字段 / more fields ...
314///         Ok((MyStruct { field1, ... }, offset))
315///     }
316/// }
317/// ```
318///
319/// ## 枚举 / Enum
320///
321/// 先读取 `u8` 变体索引,根据索引匹配对应变体,再反序列化该变体的字段。
322/// 可通过 feature 切换为 `u16` 或 `u32`。
323///
324/// First reads the `u8` variant index, matches the corresponding variant by index,
325/// then deserializes the variant's fields.
326/// Switchable to `u16` or `u32` via features.
327///
328/// ```text
329/// // 以下为生成代码的示意(非实际代码)
330/// // The following is an illustration of generated code (not actual code)
331/// impl AFastDeserialize for MyEnum {
332///     fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
333///         let mut offset: usize = 0;
334///         let (__tag, __new_offset) = <u8 as AFastDeserialize>::from_bytes(&data[offset..])?;
335///         offset += __new_offset;
336///         match __tag as usize {
337///             0 => Ok((MyEnum::Variant1, offset)),
338///             1 => {
339///                 let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
340///                 offset += __new_offset;
341///                 Ok((MyEnum::Variant2(__val), offset))
342///             }
343///             v => Err(format!("Unknown variant tag: {} for MyEnum", v)),
344///         }
345///     }
346/// }
347/// ```
348///
349/// # 泛型 / Generics
350///
351/// 如果目标类型包含泛型参数,生成的 `impl` 会同时添加 `AFastSerialize` 和
352/// `AFastDeserialize` 约束。双重约束确保泛型类型在序列化和反序列化两个方向
353/// 上都可用。
354///
355/// If the target type contains generic parameters, the generated `impl` adds both
356/// `AFastSerialize` and `AFastDeserialize` bounds. The dual bounds ensure the generic
357/// type is available in both serialization and deserialization directions.
358///
359/// # Panics
360///
361/// 对 union 类型使用此宏会触发编译 panic。
362///
363/// Using this macro on a union type will trigger a compile-time panic.
364#[proc_macro_derive(AFastDeserialize, attributes(afast))]
365pub fn derive_deserialize(input: TokenStream) -> TokenStream {
366    let input = parse_macro_input!(input as DeriveInput);
367    let name = &input.ident;
368    let generics = &input.generics;
369
370    // 为泛型参数添加 AFastSerialize + AFastDeserialize trait 约束
371    // Add AFastSerialize + AFastDeserialize trait bounds to generic parameters
372    let mut generics_with_bounds = generics.clone();
373    for param in &mut generics_with_bounds.params {
374        if let syn::GenericParam::Type(ref mut ty) = *param {
375            ty.bounds
376                .push(syn::parse_quote!(::afastdata::AFastSerialize));
377            ty.bounds
378                .push(syn::parse_quote!(::afastdata::AFastDeserialize));
379        }
380    }
381    let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
382    let (_, ty_generics, _) = generics.split_for_impl();
383
384    let expanded = match &input.data {
385        Data::Struct(data) => {
386            let (construct, field_desers) =
387                generate_deserialize_fields(&data.fields, name, &ty_generics);
388            quote! {
389                impl #impl_generics ::afastdata::AFastDeserialize for #name #ty_generics {
390                    fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::afastdata::Error> {
391                        let mut offset: usize = 0;
392                        #(#field_desers)*
393                        Ok((#construct, offset))
394                    }
395                }
396            }
397        }
398        Data::Enum(data) => {
399            let (tag_ty, _) = tag_type();
400            let mut arms = Vec::new();
401            for (i, variant) in data.variants.iter().enumerate() {
402                let variant_name = &variant.ident;
403
404                match &variant.fields {
405                    Fields::Unit => {
406                        arms.push(quote! {
407                            #i => {
408                                Ok((#name::#variant_name, offset))
409                            }
410                        });
411                    }
412                    Fields::Unnamed(fields) => {
413                        let mut field_desers = Vec::new();
414                        let mut field_names = Vec::new();
415                        for (i, f) in fields.unnamed.iter().enumerate() {
416                            let fname = syn::Ident::new(
417                                &format!("__f{}", i),
418                                variant_name.span(),
419                            );
420                            let ftype = &f.ty;
421                            let (skip, default_fn) = has_skip_attr(&f.attrs);
422                            if skip {
423                                if let Some(func_name) = default_fn {
424                                    match syn::parse_str::<syn::Ident>(&func_name) {
425                                        Ok(ident) => {
426                                            field_desers.push(quote! {
427                                                let #fname: #ftype = #ident();
428                                            });
429                                        }
430                                        Err(_) => {
431                                            field_desers.push(quote! {
432                                                compile_error!(concat!("invalid function name in skip: ", #func_name));
433                                            });
434                                        }
435                                    }
436                                } else {
437                                    field_desers.push(quote! {
438                                        let #fname: #ftype = <#ftype as ::std::default::Default>::default();
439                                    });
440                                }
441                            } else {
442                                let validates = parse_validations(&fname, ftype, &f.attrs);
443                                field_desers.push(quote! {
444                                    let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&data[offset..])?;
445                                    let #fname: #ftype = __val;
446                                    #(#validates)*
447                                    offset += __new_offset;
448                                });
449                            }
450                            field_names.push(fname);
451                        }
452                        arms.push(quote! {
453                            #i => {
454                                #(#field_desers)*
455                                Ok((#name::#variant_name(#(#field_names),*), offset))
456                            }
457                        });
458                    }
459                    Fields::Named(fields) => {
460                        let mut field_desers = Vec::new();
461                        let mut field_names = Vec::new();
462                        for f in &fields.named {
463                            let fname = f.ident.as_ref().unwrap();
464                            let ftype = &f.ty;
465                            let (skip, default_fn) = has_skip_attr(&f.attrs);
466                            if skip {
467                                if let Some(func_name) = default_fn {
468                                    match syn::parse_str::<syn::Ident>(&func_name) {
469                                        Ok(ident) => {
470                                            field_desers.push(quote! {
471                                                let #fname: #ftype = #ident();
472                                            });
473                                        }
474                                        Err(_) => {
475                                            field_desers.push(quote! {
476                                                compile_error!(concat!("invalid function name in skip: ", #func_name));
477                                            });
478                                        }
479                                    }
480                                } else {
481                                    field_desers.push(quote! {
482                                        let #fname: #ftype = <#ftype as ::std::default::Default>::default();
483                                    });
484                                }
485                            } else {
486                                let validates = parse_validations(fname, ftype, &f.attrs);
487                                field_desers.push(quote! {
488                                    let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&data[offset..])?;
489                                    let #fname: #ftype = __val;
490                                    #(#validates)*
491                                    offset += __new_offset;
492                                });
493                            }
494                            field_names.push(fname);
495                        }
496                        arms.push(quote! {
497                            #i => {
498                                #(#field_desers)*
499                                Ok((#name::#variant_name { #(#field_names),* }, offset))
500                            }
501                        });
502                    }
503                }
504            }
505
506            quote! {
507                impl #impl_generics ::afastdata::AFastDeserialize for #name #ty_generics {
508                    fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::afastdata::Error> {
509                        let mut offset: usize = 0;
510                        let (__tag_bytes, __new_offset) = <#tag_ty as ::afastdata::AFastDeserialize>::from_bytes(&data[offset..])?;
511                        offset += __new_offset;
512                        match __tag_bytes as usize {
513                            #(#arms)*
514                            v => Err(::afastdata::Error::deserialize(format!("Unknown variant tag: {} for {}", v, ::std::stringify!(#name)))),
515                        }
516                    }
517                }
518            }
519        }
520        Data::Union(_) => panic!("AFastDeserialize does not support unions"),
521    };
522
523    TokenStream::from(expanded)
524}
525
526/// 为结构体的字段生成序列化代码。内部辅助函数。
527///
528/// Generates serialization code for struct fields. Internal helper.
529///
530/// # 参数 / Parameters
531///
532/// - `fields`:结构体的字段定义 / The struct's field definitions
533/// - `self_prefix`:访问字段时使用的前缀(如 `self` 或变体解构变量)
534///   / The prefix used to access fields (e.g., `self` or a variant destructure variable)
535///
536/// # 返回值 / Returns
537///
538/// 返回一个 `TokenStream` 列表,每个元素对应一个字段的序列化语句。
539///
540/// Returns a list of `TokenStream`s, each corresponding to a serialization statement
541/// for one field.
542///
543/// # 生成格式 / Generated Format
544///
545/// - **命名字段 (Named)**:`bytes.extend(AFastSerialize::to_bytes(&self.field_name));`
546/// - **元组字段 (Unnamed)**:`bytes.extend(AFastSerialize::to_bytes(&self.0));`
547/// - **单元字段 (Unit)**:不生成任何代码 / Generates no code
548fn generate_serialize_fields(
549    fields: &Fields,
550    self_prefix: proc_macro2::TokenStream,
551) -> Vec<proc_macro2::TokenStream> {
552    match fields {
553        Fields::Named(named) => named
554            .named
555            .iter()
556            .filter(|f| !has_skip_attr(&f.attrs).0)
557            .map(|f| {
558                let fname = f.ident.as_ref().unwrap();
559                quote! {
560                    bytes.extend(::afastdata::AFastSerialize::to_bytes(&#self_prefix.#fname));
561                }
562            })
563            .collect(),
564        Fields::Unnamed(unnamed) => unnamed
565            .unnamed
566            .iter()
567            .enumerate()
568            .filter(|(_, f)| !has_skip_attr(&f.attrs).0)
569            .map(|(i, _)| {
570                let idx = Index::from(i);
571                quote! {
572                    bytes.extend(::afastdata::AFastSerialize::to_bytes(&#self_prefix.#idx));
573                }
574            })
575            .collect(),
576        Fields::Unit => vec![],
577    }
578}
579
580fn has_skip_attr(attrs: &[Attribute]) -> (bool, Option<String>) {
581    for attr in attrs {
582        if attr.path().is_ident("afast")
583            && let Ok(nested) =
584                attr.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
585        {
586            for meta in nested {
587                match meta {
588                    Meta::Path(path) if path.is_ident("skip") => {
589                        return (true, None);
590                    }
591                    Meta::List(meta_list) if meta_list.path.is_ident("skip") => {
592                        if let Ok(lit_str) = syn::parse2::<LitStr>(meta_list.tokens.clone()) {
593                            return (true, Some(lit_str.value()));
594                        } else {
595                            return (true, None);
596                        }
597                    }
598                    _ => {}
599                }
600            }
601        }
602    }
603    (false, None)
604}
605
606enum RangeValue {
607    Int(LitInt),
608    Float(LitFloat),
609}
610
611impl RangeValue {
612    fn to_token_stream(&self) -> proc_macro2::TokenStream {
613        match self {
614            RangeValue::Int(v) => quote! { #v },
615            RangeValue::Float(v) => quote! { #v },
616        }
617    }
618}
619
620struct Range {
621    value: RangeValue,
622    _comma1: Token![,],
623    code: LitInt,
624    _comma2: Token![,],
625    msg: LitStr,
626}
627
628impl Parse for Range {
629    fn parse(input: ParseStream) -> syn::Result<Self> {
630        // Try to parse as float first, then as int
631        let value = if input.peek(LitFloat) {
632            RangeValue::Float(input.parse()?)
633        } else {
634            RangeValue::Int(input.parse()?)
635        };
636        Ok(Range {
637            value,
638            _comma1: input.parse()?,
639            code: input.parse()?,
640            _comma2: input.parse()?,
641            msg: input.parse()?,
642        })
643    }
644}
645
646struct Length {
647    min: LitInt,
648    _comma1: Token![,],
649    max: LitInt,
650    _comma2: Token![,],
651    code: LitInt,
652    _comma3: Token![,],
653    msg: LitStr,
654}
655
656impl Parse for Length {
657    fn parse(input: ParseStream) -> syn::Result<Self> {
658        Ok(Length {
659            min: input.parse()?,
660            _comma1: input.parse()?,
661            max: input.parse()?,
662            _comma2: input.parse()?,
663            code: input.parse()?,
664            _comma3: input.parse()?,
665            msg: input.parse()?,
666        })
667    }
668}
669
670#[derive(Clone)]
671enum ValidateValue {
672    Int(i64),
673    Float(f64),
674    Bool(bool),
675    Str(String),
676}
677
678impl ValidateValue {
679    /// 将值转换为代码生成中使用的 TokenStream
680    ///
681    /// 例如:
682    /// ValidateValue::Int(42) → quote! { 42 }
683    /// ValidateValue::Str("hello") → quote! { "hello" }
684    fn to_token_stream(&self) -> proc_macro2::TokenStream {
685        match self {
686            ValidateValue::Int(v) => quote! { #v },
687
688            ValidateValue::Float(v) => {
689                // 浮点数通过字符串解析来保持精度
690                let v_str = v.to_string();
691                v_str.parse().unwrap_or_else(|_| {
692                    // 如果字符串解析失败,使用直接值
693                    quote! { #v }
694                })
695            }
696
697            ValidateValue::Bool(v) => quote! { #v },
698            ValidateValue::Str(v) => quote! { #v },
699        }
700    }
701}
702
703struct OfValidator {
704    allowed_values: Vec<ValidateValue>,
705    code: syn::LitInt,
706    msg: syn::LitStr,
707}
708
709impl Parse for OfValidator {
710    fn parse(input: ParseStream) -> syn::Result<Self> {
711        let content;
712        syn::bracketed!(content in input);
713
714        let mut values = Vec::new();
715
716        if !content.is_empty() {
717            loop {
718                let lit = content.parse::<Lit>()?;
719
720                let value = match lit {
721                    Lit::Int(lit_int) => {
722                        let int_value: i64 = lit_int.base10_parse()?;
723                        ValidateValue::Int(int_value)
724                    }
725
726                    Lit::Float(lit_float) => {
727                        let float_value: f64 = lit_float.base10_parse()?;
728                        ValidateValue::Float(float_value)
729                    }
730
731                    Lit::Bool(lit_bool) => ValidateValue::Bool(lit_bool.value),
732
733                    Lit::Str(lit_str) => ValidateValue::Str(lit_str.value()),
734
735                    _ => {
736                        return Err(syn::Error::new_spanned(
737                            &lit,
738                            "unsupported literal type in 'of' validator; \
739                             only int, float, bool, and str literals are supported",
740                        ));
741                    }
742                };
743
744                values.push(value);
745
746                if !content.peek(Token![,]) {
747                    break;
748                }
749
750                content.parse::<Token![,]>()?;
751
752                if content.is_empty() {
753                    break;
754                }
755            }
756        }
757
758        input.parse::<Token![,]>()?;
759
760        let code = input.parse::<syn::LitInt>()?;
761
762        input.parse::<Token![,]>()?;
763
764        let msg = input.parse::<syn::LitStr>()?;
765
766        Ok(OfValidator {
767            allowed_values: values,
768            code,
769            msg,
770        })
771    }
772}
773
774/// 检测字段类型是否为数值类型(i8..i128, u8..u128, f32, f64)。
775///
776/// Checks whether the field type is a numeric type.
777fn is_numeric_type(ty: &Type) -> bool {
778    if let Type::Path(TypePath { path, .. }) = ty {
779        if let Some(segment) = path.segments.last() {
780            let name = segment.ident.to_string();
781            return matches!(
782                name.as_str(),
783                "i8" | "i16"
784                    | "i32"
785                    | "i64"
786                    | "i128"
787                    | "u8"
788                    | "u16"
789                    | "u32"
790                    | "u64"
791                    | "u128"
792                    | "usize"
793                    | "f32"
794                    | "f64"
795            );
796        }
797    }
798    false
799}
800
801/// 检测字段类型是否为 Option<T>。
802///
803/// Checks whether the field type is `Option<T>`.
804fn is_option_type(ty: &Type) -> bool {
805    if let Type::Path(TypePath {
806        path: Path { segments, .. },
807        ..
808    }) = ty
809    {
810        segments.len() == 1 && segments[0].ident == "Option"
811    } else {
812        false
813    }
814}
815
816/// 提取 Option<T> 的内部类型 T。
817///
818/// Extracts the inner type `T` from `Option<T>`.
819fn extract_option_inner(ty: &Type) -> Option<&Type> {
820    if let Type::Path(TypePath {
821        path: Path { segments, .. },
822        ..
823    }) = ty
824    {
825        if segments.len() == 1 && segments[0].ident == "Option" {
826            if let syn::PathArguments::AngleBracketed(args) = &segments[0].arguments {
827                if let Some(syn::GenericArgument::Type(inner)) = args.args.first() {
828                    return Some(inner);
829                }
830            }
831        }
832    }
833    None
834}
835
836/// 检测字段类型是否为可进行比较校验的类型(数值类型或 Option<数值类型>)。
837///
838/// Checks whether the field type supports comparison validation
839/// (numeric type or Option<numeric type>).
840fn is_comparable_type(ty: &Type) -> bool {
841    if is_numeric_type(ty) {
842        return true;
843    }
844    if let Some(inner) = extract_option_inner(ty) {
845        return is_numeric_type(inner);
846    }
847    false
848}
849
850/// 检测字段类型是否为字符串或集合类型(String, &str, Vec<T>, [T; N])。
851///
852/// Checks whether the field type is a string or collection type.
853fn is_collection_type(ty: &Type) -> bool {
854    if let Type::Path(TypePath { path, .. }) = ty {
855        if let Some(segment) = path.segments.last() {
856            let name = segment.ident.to_string();
857            return matches!(name.as_str(), "String" | "Vec" | "BTreeSet" | "BTreeMap" | "HashSet" | "HashMap");
858        }
859    }
860    // [T; N] arrays
861    if let Type::Array(_) = ty {
862        return true;
863    }
864    // &str
865    if let Type::Reference(r) = ty {
866        if let Type::Path(TypePath { path, .. }) = &*r.elem {
867            if let Some(segment) = path.segments.last() {
868                return segment.ident == "str";
869            }
870        }
871    }
872    false
873}
874
875/// 解析字段上的 `#[afast(...)]` 校验属性,生成校验代码。
876///
877/// Parses `#[afast(...)]` validation attributes on a field and generates
878/// validation code blocks.
879///
880/// # 参数 / Parameters
881///
882/// - `field_name`:字段名 / Field name
883/// - `field_type`:字段类型 / Field type
884/// - `attrs`:字段的属性列表 / Field attributes
885///
886/// # 返回值 / Returns
887///
888/// 返回校验语句的 `TokenStream` 列表。
889///
890/// Returns a list of validation `TokenStream` blocks.
891fn parse_validations(
892    field_name: &syn::Ident,
893    field_type: &Type,
894    attrs: &[Attribute],
895) -> Vec<proc_macro2::TokenStream> {
896    let mut validates = Vec::new();
897    for attr in attrs {
898        if attr.path().is_ident("afast") {
899            let nested = match attr
900                .parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
901            {
902                Ok(n) => n,
903                Err(e) => {
904                    validates.push(e.to_compile_error());
905                    continue;
906                }
907            };
908            for meta in nested {
909                if let Meta::List(meta) = meta {
910                        if meta.path.is_ident("gt") {
911                            if !is_comparable_type(field_type) {
912                                validates.push(
913                                    syn::Error::new_spanned(
914                                        &meta.path,
915                                        format!(
916                                            "validation `gt` is only supported on numeric types or Option<numeric>, but field `{}` is not",
917                                            field_name
918                                        ),
919                                    )
920                                    .to_compile_error(),
921                                );
922                                continue;
923                            }
924                            let inner = match meta.parse_args::<Range>() {
925                                Ok(v) => v,
926                                Err(e) => {
927                                    validates.push(e.to_compile_error());
928                                    continue;
929                                }
930                            };
931                            let cmp_value = inner.value.to_token_stream();
932                            let code = match inner.code.base10_parse::<i64>() {
933                                Ok(v) => v,
934                                Err(e) => {
935                                    validates.push(
936                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
937                                            .to_compile_error(),
938                                    );
939                                    continue;
940                                }
941                            };
942                            let err_msg = inner
943                                .msg
944                                .value()
945                                .replace("${field}", &field_name.to_string());
946                            if is_option_type(field_type) {
947                                validates.push(quote! {
948                                    if let Some(ref __val) = #field_name {
949                                        if *__val <= #cmp_value {
950                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
951                                        }
952                                    }
953                                });
954                            } else {
955                                validates.push(quote! {
956                                    if #field_name <= #cmp_value {
957                                        return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
958                                    }
959                                });
960                            }
961                        } else if meta.path.is_ident("gte") {
962                            if !is_comparable_type(field_type) {
963                                validates.push(
964                                    syn::Error::new_spanned(
965                                        &meta.path,
966                                        format!(
967                                            "validation `gte` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
968                                            field_name
969                                        ),
970                                    )
971                                    .to_compile_error(),
972                                );
973                                continue;
974                            }
975                            let inner = match meta.parse_args::<Range>() {
976                                Ok(v) => v,
977                                Err(e) => {
978                                    validates.push(e.to_compile_error());
979                                    continue;
980                                }
981                            };
982                            let cmp_value = inner.value.to_token_stream();
983                            let code = match inner.code.base10_parse::<i64>() {
984                                Ok(v) => v,
985                                Err(e) => {
986                                    validates.push(
987                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
988                                            .to_compile_error(),
989                                    );
990                                    continue;
991                                }
992                            };
993                            let err_msg = inner
994                                .msg
995                                .value()
996                                .replace("${field}", &field_name.to_string());
997                            if is_option_type(field_type) {
998                                validates.push(quote! {
999                                    if let Some(ref __val) = #field_name {
1000                                        if *__val < #cmp_value {
1001                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1002                                        }
1003                                    }
1004                                });
1005                            } else {
1006                                validates.push(quote! {
1007                                    if #field_name < #cmp_value {
1008                                        return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1009                                    }
1010                                });
1011                            }
1012                        } else if meta.path.is_ident("lt") {
1013                            if !is_comparable_type(field_type) {
1014                                validates.push(
1015                                    syn::Error::new_spanned(
1016                                        &meta.path,
1017                                        format!(
1018                                            "validation `lt` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
1019                                            field_name
1020                                        ),
1021                                    )
1022                                    .to_compile_error(),
1023                                );
1024                                continue;
1025                            }
1026                            let inner = match meta.parse_args::<Range>() {
1027                                Ok(v) => v,
1028                                Err(e) => {
1029                                    validates.push(e.to_compile_error());
1030                                    continue;
1031                                }
1032                            };
1033                            let cmp_value = inner.value.to_token_stream();
1034                            let code = match inner.code.base10_parse::<i64>() {
1035                                Ok(v) => v,
1036                                Err(e) => {
1037                                    validates.push(
1038                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
1039                                            .to_compile_error(),
1040                                    );
1041                                    continue;
1042                                }
1043                            };
1044                            let err_msg = inner
1045                                .msg
1046                                .value()
1047                                .replace("${field}", &field_name.to_string());
1048                            if is_option_type(field_type) {
1049                                validates.push(quote! {
1050                                    if let Some(ref __val) = #field_name {
1051                                        if *__val >= #cmp_value {
1052                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1053                                        }
1054                                    }
1055                                });
1056                            } else {
1057                                validates.push(quote! {
1058                                    if #field_name >= #cmp_value {
1059                                        return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1060                                    }
1061                                });
1062                            }
1063                        } else if meta.path.is_ident("lte") {
1064                            if !is_comparable_type(field_type) {
1065                                validates.push(
1066                                    syn::Error::new_spanned(
1067                                        &meta.path,
1068                                        format!(
1069                                            "validation `lte` is only supported on numeric types (or Option<numeric>), but field `{}` is not",
1070                                            field_name
1071                                        ),
1072                                    )
1073                                    .to_compile_error(),
1074                                );
1075                                continue;
1076                            }
1077                            let inner = match meta.parse_args::<Range>() {
1078                                Ok(v) => v,
1079                                Err(e) => {
1080                                    validates.push(e.to_compile_error());
1081                                    continue;
1082                                }
1083                            };
1084                            let cmp_value = inner.value.to_token_stream();
1085                            let code = match inner.code.base10_parse::<i64>() {
1086                                Ok(v) => v,
1087                                Err(e) => {
1088                                    validates.push(
1089                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
1090                                            .to_compile_error(),
1091                                    );
1092                                    continue;
1093                                }
1094                            };
1095                            let err_msg = inner
1096                                .msg
1097                                .value()
1098                                .replace("${field}", &field_name.to_string());
1099                            if is_option_type(field_type) {
1100                                validates.push(quote! {
1101                                    if let Some(ref __val) = #field_name {
1102                                        if *__val > #cmp_value {
1103                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1104                                        }
1105                                    }
1106                                });
1107                            } else {
1108                                validates.push(quote! {
1109                                    if #field_name > #cmp_value {
1110                                        return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1111                                    }
1112                                });
1113                            }
1114                        } else if meta.path.is_ident("len") {
1115                            let field_is_option = is_option_type(field_type);
1116                            // For Option<T>, check if inner type is a collection
1117                            // For non-Option, check directly
1118                            if field_is_option {
1119                                // Option<T> is allowed - inner type check is deferred to runtime
1120                            } else if !is_collection_type(field_type) {
1121                                validates.push(
1122                                    syn::Error::new_spanned(
1123                                        &meta.path,
1124                                        format!(
1125                                            "validation `len` is only supported on String, &[u8], Vec<T>, [T; N], or Option<T> wrapping these types, but field `{}` is not",
1126                                            field_name
1127                                        ),
1128                                    )
1129                                    .to_compile_error(),
1130                                );
1131                                continue;
1132                            }
1133
1134                            let inner = match meta.parse_args::<Length>() {
1135                                Ok(v) => v,
1136                                Err(e) => {
1137                                    validates.push(e.to_compile_error());
1138                                    continue;
1139                                }
1140                            };
1141                            let min_value = match inner.min.base10_parse::<i64>() {
1142                                Ok(v) => v,
1143                                Err(e) => {
1144                                    validates.push(
1145                                        syn::Error::new_spanned(&inner.min, format!("invalid min value: {}", e))
1146                                            .to_compile_error(),
1147                                    );
1148                                    continue;
1149                                }
1150                            };
1151                            let max_value = match inner.max.base10_parse::<i64>() {
1152                                Ok(v) => v,
1153                                Err(e) => {
1154                                    validates.push(
1155                                        syn::Error::new_spanned(&inner.max, format!("invalid max value: {}", e))
1156                                            .to_compile_error(),
1157                                    );
1158                                    continue;
1159                                }
1160                            };
1161                            let code = match inner.code.base10_parse::<i64>() {
1162                                Ok(v) => v,
1163                                Err(e) => {
1164                                    validates.push(
1165                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
1166                                            .to_compile_error(),
1167                                    );
1168                                    continue;
1169                                }
1170                            };
1171                            let err_msg = inner
1172                                .msg
1173                                .value()
1174                                .replace("${field}", &field_name.to_string());
1175                            // -1 is a sentinel meaning "no limit", so skip range check when either is -1
1176                            if min_value >= 0 && max_value >= 0 && min_value > max_value {
1177                                validates.push(
1178                                    syn::Error::new_spanned(
1179                                        &meta.path,
1180                                        format!(
1181                                            "invalid len validation: min ({}) > max ({}) for field `{}`",
1182                                            min_value, max_value, field_name
1183                                        ),
1184                                    )
1185                                    .to_compile_error(),
1186                                );
1187                                continue;
1188                            }
1189                            if min_value < 0 && max_value < 0 {
1190                                validates.push(
1191                                    syn::Error::new_spanned(
1192                                        &meta.path,
1193                                        format!(
1194                                            "invalid len validation: both min and max are negative for field `{}`",
1195                                            field_name
1196                                        ),
1197                                    )
1198                                    .to_compile_error(),
1199                                );
1200                                continue;
1201                            } else if min_value < 0 {
1202                                let max: usize = match max_value.try_into() {
1203                                    Ok(v) => v,
1204                                    Err(_) => {
1205                                        validates.push(
1206                                            syn::Error::new_spanned(&inner.max, "value too large for usize")
1207                                                .to_compile_error(),
1208                                        );
1209                                        continue;
1210                                    }
1211                                };
1212                                if field_is_option {
1213                                    validates.push(quote! {
1214                                        if let Some(ref __val) = #field_name {
1215                                            if __val.len() > #max {
1216                                                return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1217                                            }
1218                                        }
1219                                    });
1220                                } else {
1221                                    validates.push(quote! {
1222                                        if #field_name.len() > #max {
1223                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1224                                        }
1225                                    });
1226                                }
1227                            } else if max_value < 0 {
1228                                let min: usize = match min_value.try_into() {
1229                                    Ok(v) => v,
1230                                    Err(_) => {
1231                                        validates.push(
1232                                            syn::Error::new_spanned(&inner.min, "value too large for usize")
1233                                                .to_compile_error(),
1234                                        );
1235                                        continue;
1236                                    }
1237                                };
1238                                if field_is_option {
1239                                    validates.push(quote! {
1240                                        if let Some(ref __val) = #field_name {
1241                                            if __val.len() < #min {
1242                                                return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1243                                            }
1244                                        }
1245                                    });
1246                                } else {
1247                                    validates.push(quote! {
1248                                        if #field_name.len() < #min {
1249                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1250                                        }
1251                                    });
1252                                }
1253                            } else {
1254                                let min: usize = match min_value.try_into() {
1255                                    Ok(v) => v,
1256                                    Err(_) => {
1257                                        validates.push(
1258                                            syn::Error::new_spanned(&inner.min, "value too large for usize")
1259                                                .to_compile_error(),
1260                                        );
1261                                        continue;
1262                                    }
1263                                };
1264                                let max: usize = match max_value.try_into() {
1265                                    Ok(v) => v,
1266                                    Err(_) => {
1267                                        validates.push(
1268                                            syn::Error::new_spanned(&inner.max, "value too large for usize")
1269                                                .to_compile_error(),
1270                                        );
1271                                        continue;
1272                                    }
1273                                };
1274                                if field_is_option {
1275                                    validates.push(quote! {
1276                                        let length = match &#field_name {
1277                                            Some(s) => {
1278                                                let __length = s.len();
1279                                                if __length < #min || __length > #max {
1280                                                    return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1281                                                }
1282                                            },
1283                                            None => {},
1284                                        };
1285                                    });
1286                                } else {
1287                                    validates.push(quote! {
1288                                        if #field_name.len() < #min || #field_name.len() > #max {
1289                                            return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1290                                        }
1291                                    });
1292                                }
1293                            }
1294                        } else if meta.path.is_ident("of") {
1295                            let inner = match meta.parse_args::<OfValidator>() {
1296                                Ok(v) => v,
1297                                Err(e) => {
1298                                    validates.push(e.to_compile_error());
1299                                    continue;
1300                                }
1301                            };
1302                            let allowed_values = inner.allowed_values.clone();
1303                            let code = match inner.code.base10_parse::<i64>() {
1304                                Ok(v) => v,
1305                                Err(e) => {
1306                                    validates.push(
1307                                        syn::Error::new_spanned(&inner.code, format!("invalid error code: {}", e))
1308                                            .to_compile_error(),
1309                                    );
1310                                    continue;
1311                                }
1312                            };
1313                            let err_msg = inner
1314                                .msg
1315                                .value()
1316                                .replace("${field}", &field_name.to_string());
1317                            let values_tokens: Vec<_> = allowed_values
1318                                .iter()
1319                                .map(|v| v.to_token_stream())
1320                                .collect();
1321                            validates.push(quote! {
1322                                if !matches!(#field_name, #(#values_tokens)|*) {
1323                                    return Err(::afastdata::Error::validate(#code, #err_msg.to_string()));
1324                                }
1325                            });
1326                        } else if meta.path.is_ident("func") {
1327                            let inner = match meta.parse_args::<LitStr>() {
1328                                Ok(v) => v,
1329                                Err(e) => {
1330                                    validates.push(e.to_compile_error());
1331                                    continue;
1332                                }
1333                            };
1334                            let ident = match syn::parse_str::<syn::Ident>(&inner.value()) {
1335                                Ok(v) => v,
1336                                Err(e) => {
1337                                    validates.push(
1338                                        syn::Error::new_spanned(
1339                                            &inner,
1340                                            format!("invalid function name `{}`: {}", inner.value(), e),
1341                                        )
1342                                        .to_compile_error(),
1343                                    );
1344                                    continue;
1345                                }
1346                            };
1347                            let field = field_name.to_string();
1348                            validates.push(quote! {
1349                                match #ident(&#field_name, #field) {
1350                                    Ok(()) => {},
1351                                    Err(e) => return Err(e.to_afastdata_error()),
1352                                }
1353                            });
1354                        }
1355                }
1356            }
1357        }
1358    }
1359    validates
1360}
1361
1362/// 为结构体的字段生成反序列化代码以及构造表达式。内部辅助函数。
1363///
1364/// Generates deserialization code for struct fields along with the construction
1365/// expression. Internal helper.
1366///
1367/// # 参数 / Parameters
1368///
1369/// - `fields`:结构体的字段定义 / The struct's field definitions
1370/// - `name`:结构体类型的标识符 / The struct type's identifier
1371/// - `ty_generics`:类型的泛型参数(用于构造时的 turbofish 语法)
1372///   / The type's generic parameters (used for turbofish syntax during construction)
1373///
1374/// # 返回值 / Returns
1375///
1376/// 返回 `(构造表达式, 反序列化语句列表)`:
1377/// - 构造表达式:用于创建结构体实例的 `TokenStream`
1378/// - 反序列化语句:每个字段的 `from_bytes()` 调用和偏移量更新
1379///
1380/// Returns `(construction_expression, deserialization_statements)`:
1381/// - Construction expression: A `TokenStream` for creating the struct instance
1382/// - Deserialization statements: `from_bytes()` calls and offset updates for each field
1383///
1384/// # 泛型构造 / Generic Construction
1385///
1386/// 使用 `as_turbofish()` 生成正确的泛型语法。例如 `MyStruct::<T>` 而非
1387/// `MyStruct <T>`(后者会被解析为比较操作)。
1388///
1389/// Uses `as_turbofish()` to generate correct generic syntax. For example,
1390/// `MyStruct::<T>` instead of `MyStruct <T>` (which would be parsed as a
1391/// comparison operation).
1392fn generate_deserialize_fields(
1393    fields: &Fields,
1394    name: &syn::Ident,
1395    ty_generics: &syn::TypeGenerics,
1396) -> (proc_macro2::TokenStream, Vec<proc_macro2::TokenStream>) {
1397    // 在表达式上下文中使用 turbofish 语法:Name::<T>
1398    // In expression context, use turbofish syntax: Name::<T>
1399    let ty_params = ty_generics.as_turbofish();
1400    match fields {
1401        Fields::Named(named) => {
1402            let mut desers = Vec::new();
1403            let mut field_names = Vec::new();
1404            for f in &named.named {
1405                let fname = f.ident.as_ref().unwrap();
1406                let ftype = &f.ty;
1407                field_names.push(fname.clone());
1408
1409                let validates = parse_validations(fname, ftype, &f.attrs);
1410                let (skip, default) = has_skip_attr(&f.attrs);
1411                if skip {
1412                    if let Some(default) = default {
1413                        match syn::parse_str::<syn::Ident>(&default) {
1414                            Ok(ident) => {
1415                                desers.push(quote! {
1416                                    let #fname: #ftype = #ident();
1417                                });
1418                            }
1419                            Err(_) => {
1420                                desers.push(quote! {
1421                                    compile_error!(concat!("invalid function name in skip: ", #default));
1422                                });
1423                            }
1424                        }
1425                    } else {
1426                        desers.push(quote! {
1427                            let #fname: #ftype = #ftype::default();
1428                        });
1429                    }
1430                } else {
1431                    desers.push(quote! {
1432                        let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&data[offset..])?;
1433                        let #fname: #ftype = __val;
1434                        #(#validates)*
1435                        offset += __new_offset;
1436                    });
1437                }
1438            }
1439            let construct = quote! {
1440                #name #ty_params { #(#field_names),* }
1441            };
1442            (construct, desers)
1443        }
1444        Fields::Unnamed(unnamed) => {
1445            let mut desers = Vec::new();
1446            let mut field_names = Vec::new();
1447            for (i, f) in unnamed.unnamed.iter().enumerate() {
1448                let fname = syn::Ident::new(&format!("__f{}", i), name.span());
1449                let ftype = &f.ty;
1450                let (skip, default_fn) = has_skip_attr(&f.attrs);
1451                if skip {
1452                    if let Some(func_name) = default_fn {
1453                        match syn::parse_str::<syn::Ident>(&func_name) {
1454                            Ok(ident) => {
1455                                desers.push(quote! {
1456                                    let #fname: #ftype = #ident();
1457                                });
1458                            }
1459                            Err(_) => {
1460                                desers.push(quote! {
1461                                    compile_error!(concat!("invalid function name in skip: ", #func_name));
1462                                });
1463                            }
1464                        }
1465                    } else {
1466                        desers.push(quote! {
1467                            let #fname: #ftype = <#ftype as ::std::default::Default>::default();
1468                        });
1469                    }
1470                } else {
1471                    let validates = parse_validations(&fname, ftype, &f.attrs);
1472                    desers.push(quote! {
1473                        let (__val, __new_offset) = ::afastdata::AFastDeserialize::from_bytes(&data[offset..])?;
1474                        let #fname: #ftype = __val;
1475                        #(#validates)*
1476                        offset += __new_offset;
1477                    });
1478                }
1479                field_names.push(fname);
1480            }
1481            let construct = quote! {
1482                #name #ty_params ( #(#field_names),* )
1483            };
1484            (construct, desers)
1485        }
1486        Fields::Unit => {
1487            let construct = quote! { #name #ty_params };
1488            (construct, vec![])
1489        }
1490    }
1491}