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//! ```ignore
49//! use afastdata::{AFastSerialize, AFastDeserialize};
50//!
51//! #[derive(AFastSerialize, AFastDeserialize, Debug, PartialEq)]
52//! struct Point {
53//! x: i32,
54//! y: i32,
55//! }
56//!
57//! #[derive(AFastSerialize, AFastDeserialize, Debug, PartialEq)]
58//! enum Shape {
59//! Circle(f64),
60//! Rectangle { width: f64, height: f64 },
61//! Empty,
62//! }
63//!
64//! // 序列化 / Serialize
65//! let point = Point { x: 10, y: 20 };
66//! let bytes = point.to_bytes();
67//!
68//! // 反序列化 / Deserialize
69//! let (decoded, _) = Point::from_bytes(&bytes).unwrap();
70//! assert_eq!(point, decoded);
71//! ```
72
73use proc_macro::TokenStream;
74use quote::quote;
75use syn::{
76 parse::{Parse, ParseStream},
77 parse_macro_input,
78 punctuated::Punctuated,
79 Data, DeriveInput, Fields, Index, LitInt, LitStr, Meta, Path, Token, Type, TypePath,
80};
81
82/// 为结构体或枚举生成 [`AFastSerialize`] trait 实现。
83///
84/// Generates an [`AFastSerialize`] trait implementation for a struct or enum.
85///
86/// # 生成的代码 / Generated Code
87///
88/// ## 结构体 / Struct
89///
90/// 为每个字段调用 `to_bytes()`,并将结果依次追加到字节缓冲区中。
91///
92/// Calls `to_bytes()` on each field, appending the results to a byte buffer
93/// sequentially.
94///
95/// ```ignore
96/// // 以下为生成代码的示意(非实际代码)
97/// // The following is an illustration of generated code (not actual code)
98/// impl AFastSerialize for MyStruct {
99/// fn to_bytes(&self) -> Vec<u8> {
100/// let mut bytes = Vec::new();
101/// bytes.extend(AFastSerialize::to_bytes(&self.field1));
102/// bytes.extend(AFastSerialize::to_bytes(&self.field2));
103/// // ...
104/// bytes
105/// }
106/// }
107/// ```
108///
109/// ## 枚举 / Enum
110///
111/// 先写入 `u32` 变体索引(从 0 开始),再写入变体的字段数据。
112/// Unit 变体只写入索引。
113///
114/// Writes a `u32` variant index (starting from 0), then the variant's field data.
115/// Unit variants only write the index.
116///
117/// ```ignore
118/// // 以下为生成代码的示意(非实际代码)
119/// // The following is an illustration of generated code (not actual code)
120/// impl AFastSerialize for MyEnum {
121/// fn to_bytes(&self) -> Vec<u8> {
122/// let mut bytes = Vec::new();
123/// match self {
124/// MyEnum::Variant1 => {
125/// bytes.extend(0u32.to_le_bytes());
126/// }
127/// MyEnum::Variant2(field) => {
128/// bytes.extend(1u32.to_le_bytes());
129/// bytes.extend(AFastSerialize::to_bytes(field));
130/// }
131/// // ...
132/// }
133/// bytes
134/// }
135/// }
136/// ```
137///
138/// # 泛型 / Generics
139///
140/// 如果目标类型包含泛型参数,生成的 `impl` 会自动为这些参数添加
141/// `AFastSerialize` 约束。
142///
143/// If the target type contains generic parameters, the generated `impl` automatically
144/// adds `AFastSerialize` bounds to those parameters.
145///
146/// # Panics
147///
148/// 对 union 类型使用此宏会触发编译 panic。
149///
150/// Using this macro on a union type will trigger a compile-time panic.
151#[proc_macro_derive(AFastSerialize, attributes(validate))]
152pub fn derive_serialize(input: TokenStream) -> TokenStream {
153 let input = parse_macro_input!(input as DeriveInput);
154 let name = &input.ident;
155 let generics = &input.generics;
156
157 // 为泛型参数添加 AFastSerialize trait 约束
158 // Add AFastSerialize trait bounds to generic parameters
159 let mut generics_with_bounds = generics.clone();
160 for param in &mut generics_with_bounds.params {
161 if let syn::GenericParam::Type(ref mut ty) = *param {
162 ty.bounds
163 .push(syn::parse_quote!(::afastdata_core::AFastSerialize));
164 }
165 }
166 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
167 let (_, ty_generics, _) = generics.split_for_impl();
168
169 let expanded = match &input.data {
170 Data::Struct(data) => {
171 let serialize_body = generate_serialize_fields(&data.fields, quote!(self));
172 quote! {
173 impl #impl_generics ::afastdata_core::AFastSerialize for #name #ty_generics {
174 fn to_bytes(&self) -> Vec<u8> {
175 let mut bytes = Vec::new();
176 #(#serialize_body)*
177 bytes
178 }
179 }
180 }
181 }
182 Data::Enum(data) => {
183 let mut arms = Vec::new();
184 for (i, variant) in data.variants.iter().enumerate() {
185 let variant_name = &variant.ident;
186 let tag = i as u32;
187
188 match &variant.fields {
189 Fields::Unit => {
190 // Unit 变体:只写入 u32 索引
191 // Unit variant: write only the u32 index
192 arms.push(quote! {
193 #name::#variant_name => {
194 bytes.extend(#tag.to_le_bytes());
195 }
196 });
197 }
198 Fields::Unnamed(fields) => {
199 // 元组变体:写入 u32 索引 + 逐字段序列化
200 // Tuple variant: write u32 index + field-by-field serialization
201 let field_names: Vec<_> = (0..fields.unnamed.len())
202 .map(|i| {
203 let ident =
204 syn::Ident::new(&format!("__f{}", i), variant_name.span());
205 ident
206 })
207 .collect();
208 let field_patterns = &field_names;
209 let mut serialize_fields = Vec::new();
210 for fname in &field_names {
211 serialize_fields.push(quote! {
212 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(#fname));
213 });
214 }
215 arms.push(quote! {
216 #name::#variant_name(#(#field_patterns),*) => {
217 bytes.extend(#tag.to_le_bytes());
218 #(#serialize_fields)*
219 }
220 });
221 }
222 Fields::Named(fields) => {
223 // 命名字段变体:写入 u32 索引 + 逐字段序列化
224 // Named-field variant: write u32 index + field-by-field serialization
225 let field_names: Vec<_> = fields
226 .named
227 .iter()
228 .map(|f| f.ident.as_ref().unwrap())
229 .collect();
230 let mut serialize_fields = Vec::new();
231 for fname in &field_names {
232 serialize_fields.push(quote! {
233 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(#fname));
234 });
235 }
236 arms.push(quote! {
237 #name::#variant_name { #(#field_names),* } => {
238 bytes.extend(#tag.to_le_bytes());
239 #(#serialize_fields)*
240 }
241 });
242 }
243 }
244 }
245
246 quote! {
247 impl #impl_generics ::afastdata_core::AFastSerialize for #name #ty_generics {
248 fn to_bytes(&self) -> Vec<u8> {
249 let mut bytes = Vec::new();
250 match self {
251 #(#arms)*
252 }
253 bytes
254 }
255 }
256 }
257 }
258 Data::Union(_) => panic!("AFastSerialize does not support unions"),
259 };
260
261 TokenStream::from(expanded)
262}
263
264/// 为结构体或枚举生成 [`AFastDeserialize`] trait 实现。
265///
266/// Generates an [`AFastDeserialize`] trait implementation for a struct or enum.
267///
268/// # 生成的代码 / Generated Code
269///
270/// ## 结构体 / Struct
271///
272/// 为每个字段依次调用 `from_bytes()`,并使用偏移量追踪已消耗的字节数,
273/// 最后构造结构体实例。
274///
275/// Calls `from_bytes()` on each field sequentially, using an offset to track
276/// consumed bytes, then constructs the struct instance.
277///
278/// ```ignore
279/// // 以下为生成代码的示意(非实际代码)
280/// // The following is an illustration of generated code (not actual code)
281/// impl AFastDeserialize for MyStruct {
282/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
283/// let mut offset: usize = 0;
284/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
285/// let field1 = __val;
286/// offset += __new_offset;
287/// // ... 更多字段 / more fields ...
288/// Ok((MyStruct { field1, ... }, offset))
289/// }
290/// }
291/// ```
292///
293/// ## 枚举 / Enum
294///
295/// 先读取 `u32` 变体索引,根据索引匹配对应变体,再反序列化该变体的字段。
296///
297/// First reads the `u32` variant index, matches the corresponding variant by index,
298/// then deserializes the variant's fields.
299///
300/// ```ignore
301/// // 以下为生成代码的示意(非实际代码)
302/// // The following is an illustration of generated code (not actual code)
303/// impl AFastDeserialize for MyEnum {
304/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), Error> {
305/// let mut offset: usize = 0;
306/// let (__tag, __new_offset) = <u32 as AFastDeserialize>::from_bytes(&data[offset..])?;
307/// offset += __new_offset;
308/// match __tag {
309/// 0 => Ok((MyEnum::Variant1, offset)),
310/// 1 => {
311/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
312/// offset += __new_offset;
313/// Ok((MyEnum::Variant2(__val), offset))
314/// }
315/// v => Err(format!("Unknown variant tag: {} for MyEnum", v)),
316/// }
317/// }
318/// }
319/// ```
320///
321/// # 泛型 / Generics
322///
323/// 如果目标类型包含泛型参数,生成的 `impl` 会同时添加 `AFastSerialize` 和
324/// `AFastDeserialize` 约束。双重约束确保泛型类型在序列化和反序列化两个方向
325/// 上都可用。
326///
327/// If the target type contains generic parameters, the generated `impl` adds both
328/// `AFastSerialize` and `AFastDeserialize` bounds. The dual bounds ensure the generic
329/// type is available in both serialization and deserialization directions.
330///
331/// # Panics
332///
333/// 对 union 类型使用此宏会触发编译 panic。
334///
335/// Using this macro on a union type will trigger a compile-time panic.
336#[proc_macro_derive(AFastDeserialize, attributes(validate))]
337pub fn derive_deserialize(input: TokenStream) -> TokenStream {
338 let input = parse_macro_input!(input as DeriveInput);
339 let name = &input.ident;
340 let generics = &input.generics;
341
342 // 为泛型参数添加 AFastSerialize + AFastDeserialize trait 约束
343 // Add AFastSerialize + AFastDeserialize trait bounds to generic parameters
344 let mut generics_with_bounds = generics.clone();
345 for param in &mut generics_with_bounds.params {
346 if let syn::GenericParam::Type(ref mut ty) = *param {
347 ty.bounds
348 .push(syn::parse_quote!(::afastdata_core::AFastSerialize));
349 ty.bounds
350 .push(syn::parse_quote!(::afastdata_core::AFastDeserialize));
351 }
352 }
353 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
354 let (_, ty_generics, _) = generics.split_for_impl();
355
356 let expanded = match &input.data {
357 Data::Struct(data) => {
358 let (construct, field_desers) =
359 generate_deserialize_fields(&data.fields, &name, &ty_generics);
360 quote! {
361 impl #impl_generics ::afastdata_core::AFastDeserialize for #name #ty_generics {
362 fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::afastdata_core::Error> {
363 let mut offset: usize = 0;
364 #(#field_desers)*
365 Ok((#construct, offset))
366 }
367 }
368 }
369 }
370 Data::Enum(data) => {
371 let mut arms = Vec::new();
372 for (i, variant) in data.variants.iter().enumerate() {
373 let variant_name = &variant.ident;
374 let tag = i as u32;
375
376 match &variant.fields {
377 Fields::Unit => {
378 // Unit 变体:匹配索引后直接返回
379 // Unit variant: match index and return directly
380 arms.push(quote! {
381 #tag => {
382 Ok((#name::#variant_name, offset))
383 }
384 });
385 }
386 Fields::Unnamed(fields) => {
387 // 元组变体:匹配索引后逐字段反序列化
388 // Tuple variant: match index, then deserialize fields sequentially
389 let mut field_desers = Vec::new();
390 let mut field_names = Vec::new();
391 for _ in &fields.unnamed {
392 let fname = syn::Ident::new(
393 &format!("__f{}", field_names.len()),
394 variant_name.span(),
395 );
396 field_desers.push(quote! {
397 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
398 let #fname = __val;
399 offset += __new_offset;
400 });
401 field_names.push(fname);
402 }
403 arms.push(quote! {
404 #tag => {
405 #(#field_desers)*
406 Ok((#name::#variant_name(#(#field_names),*), offset))
407 }
408 });
409 }
410 Fields::Named(fields) => {
411 // 命名字段变体:匹配索引后逐字段反序列化
412 // Named-field variant: match index, then deserialize fields sequentially
413 let mut field_desers = Vec::new();
414 let mut field_names = Vec::new();
415 for f in &fields.named {
416 let fname = f.ident.as_ref().unwrap();
417 field_desers.push(quote! {
418 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
419 let #fname = __val;
420 offset += __new_offset;
421 });
422 field_names.push(fname);
423 }
424 arms.push(quote! {
425 #tag => {
426 #(#field_desers)*
427 Ok((#name::#variant_name { #(#field_names),* }, offset))
428 }
429 });
430 }
431 }
432 }
433
434 quote! {
435 impl #impl_generics ::afastdata_core::AFastDeserialize for #name #ty_generics {
436 fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::afastdata_core::Error> {
437 let mut offset: usize = 0;
438 // 读取 u32 变体索引
439 // Read the u32 variant index
440 let (__tag_bytes, __new_offset) = <u32 as ::afastdata_core::AFastDeserialize>::from_bytes(&data[offset..])?;
441 offset += __new_offset;
442 match __tag_bytes {
443 #(#arms)*
444 v => Err(::afastdata_core::Error::deserialize(format!("Unknown variant tag: {} for {}", v, ::std::stringify!(#name)))),
445 }
446 }
447 }
448 }
449 }
450 Data::Union(_) => panic!("AFastDeserialize does not support unions"),
451 };
452
453 TokenStream::from(expanded)
454}
455
456/// 为结构体的字段生成序列化代码。内部辅助函数。
457///
458/// Generates serialization code for struct fields. Internal helper.
459///
460/// # 参数 / Parameters
461///
462/// - `fields`:结构体的字段定义 / The struct's field definitions
463/// - `self_prefix`:访问字段时使用的前缀(如 `self` 或变体解构变量)
464/// / The prefix used to access fields (e.g., `self` or a variant destructure variable)
465///
466/// # 返回值 / Returns
467///
468/// 返回一个 `TokenStream` 列表,每个元素对应一个字段的序列化语句。
469///
470/// Returns a list of `TokenStream`s, each corresponding to a serialization statement
471/// for one field.
472///
473/// # 生成格式 / Generated Format
474///
475/// - **命名字段 (Named)**:`bytes.extend(AFastSerialize::to_bytes(&self.field_name));`
476/// - **元组字段 (Unnamed)**:`bytes.extend(AFastSerialize::to_bytes(&self.0));`
477/// - **单元字段 (Unit)**:不生成任何代码 / Generates no code
478fn generate_serialize_fields(
479 fields: &Fields,
480 self_prefix: proc_macro2::TokenStream,
481) -> Vec<proc_macro2::TokenStream> {
482 match fields {
483 Fields::Named(named) => named
484 .named
485 .iter()
486 .map(|f| {
487 let fname = f.ident.as_ref().unwrap();
488 quote! {
489 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(&#self_prefix.#fname));
490 }
491 })
492 .collect(),
493 Fields::Unnamed(unnamed) => unnamed
494 .unnamed
495 .iter()
496 .enumerate()
497 .map(|(i, _)| {
498 let idx = Index::from(i);
499 quote! {
500 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(&#self_prefix.#idx));
501 }
502 })
503 .collect(),
504 Fields::Unit => vec![],
505 }
506}
507
508struct Range {
509 int: LitInt,
510 _comma1: Token![,],
511 code: LitInt,
512 _comma2: Token![,],
513 msg: LitStr,
514}
515
516impl Parse for Range {
517 fn parse(input: ParseStream) -> syn::Result<Self> {
518 Ok(Range {
519 int: input.parse()?,
520 _comma1: input.parse()?,
521 code: input.parse()?,
522 _comma2: input.parse()?,
523 msg: input.parse()?,
524 })
525 }
526}
527
528struct Length {
529 min: LitInt,
530 _comma1: Token![,],
531 max: LitInt,
532 _comma2: Token![,],
533 code: LitInt,
534 _comma3: Token![,],
535 msg: LitStr,
536}
537
538impl Parse for Length {
539 fn parse(input: ParseStream) -> syn::Result<Self> {
540 Ok(Length {
541 min: input.parse()?,
542 _comma1: input.parse()?,
543 max: input.parse()?,
544 _comma2: input.parse()?,
545 code: input.parse()?,
546 _comma3: input.parse()?,
547 msg: input.parse()?,
548 })
549 }
550}
551
552/// 为结构体的字段生成反序列化代码以及构造表达式。内部辅助函数。
553///
554/// Generates deserialization code for struct fields along with the construction
555/// expression. Internal helper.
556///
557/// # 参数 / Parameters
558///
559/// - `fields`:结构体的字段定义 / The struct's field definitions
560/// - `name`:结构体类型的标识符 / The struct type's identifier
561/// - `ty_generics`:类型的泛型参数(用于构造时的 turbofish 语法)
562/// / The type's generic parameters (used for turbofish syntax during construction)
563///
564/// # 返回值 / Returns
565///
566/// 返回 `(构造表达式, 反序列化语句列表)`:
567/// - 构造表达式:用于创建结构体实例的 `TokenStream`
568/// - 反序列化语句:每个字段的 `from_bytes()` 调用和偏移量更新
569///
570/// Returns `(construction_expression, deserialization_statements)`:
571/// - Construction expression: A `TokenStream` for creating the struct instance
572/// - Deserialization statements: `from_bytes()` calls and offset updates for each field
573///
574/// # 泛型构造 / Generic Construction
575///
576/// 使用 `as_turbofish()` 生成正确的泛型语法。例如 `MyStruct::<T>` 而非
577/// `MyStruct <T>`(后者会被解析为比较操作)。
578///
579/// Uses `as_turbofish()` to generate correct generic syntax. For example,
580/// `MyStruct::<T>` instead of `MyStruct <T>` (which would be parsed as a
581/// comparison operation).
582fn generate_deserialize_fields(
583 fields: &Fields,
584 name: &syn::Ident,
585 ty_generics: &syn::TypeGenerics,
586) -> (proc_macro2::TokenStream, Vec<proc_macro2::TokenStream>) {
587 // 在表达式上下文中使用 turbofish 语法:Name::<T>
588 // In expression context, use turbofish syntax: Name::<T>
589 let ty_params = ty_generics.as_turbofish();
590 match fields {
591 Fields::Named(named) => {
592 let mut desers = Vec::new();
593 let mut field_names = Vec::new();
594 for f in &named.named {
595 let fname = f.ident.as_ref().unwrap();
596 let ftype = &f.ty;
597 field_names.push(fname.clone());
598
599 let mut validates = Vec::new();
600 for attr in &f.attrs {
601 if attr.path().is_ident("validate") {
602 let nested = attr
603 .parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
604 .unwrap();
605 for meta in nested {
606 match meta {
607 Meta::List(meta) => {
608 if meta.path.is_ident("gt") {
609 let inner = meta.parse_args::<Range>().unwrap();
610 let gt_value = inner.int.base10_parse::<i64>().unwrap();
611 let code = inner.code.base10_parse::<i64>().unwrap();
612 let err_msg = inner
613 .msg
614 .value()
615 .replace("${field}", &fname.to_string());
616 validates.push(quote! {
617 if #fname <= #gt_value {
618 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
619 }
620 });
621 } else if meta.path.is_ident("gte") {
622 let inner = meta.parse_args::<Range>().unwrap();
623 let gt_value = inner.int.base10_parse::<i64>().unwrap();
624 let code = inner.code.base10_parse::<i64>().unwrap();
625 let err_msg = inner
626 .msg
627 .value()
628 .replace("${field}", &fname.to_string());
629 validates.push(quote! {
630 if #fname < #gt_value {
631 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
632 }
633 });
634 } else if meta.path.is_ident("lt") {
635 let inner = meta.parse_args::<Range>().unwrap();
636 let lt_value = inner.int.base10_parse::<i64>().unwrap();
637 let code = inner.code.base10_parse::<i64>().unwrap();
638 let err_msg = inner
639 .msg
640 .value()
641 .replace("${field}", &fname.to_string());
642 validates.push(quote! {
643 if #fname >= #lt_value {
644 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
645 }
646 });
647 } else if meta.path.is_ident("lte") {
648 let inner = meta.parse_args::<Range>().unwrap();
649 let lt_value = inner.int.base10_parse::<i64>().unwrap();
650 let code = inner.code.base10_parse::<i64>().unwrap();
651 let err_msg = inner
652 .msg
653 .value()
654 .replace("${field}", &fname.to_string());
655 validates.push(quote! {
656 if #fname > #lt_value {
657 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
658 }
659 });
660 } else if meta.path.is_ident("len") {
661 let field_is_option = match ftype {
662 Type::Path(TypePath {
663 path: Path { segments, .. },
664 ..
665 }) => {
666 segments.len() == 1 && segments[0].ident == "Option"
667 }
668 _ => false,
669 };
670
671 let inner = meta.parse_args::<Length>().unwrap();
672 let min_value = inner.min.base10_parse::<i64>().unwrap();
673 let max_value = inner.max.base10_parse::<i64>().unwrap();
674 let code = inner.code.base10_parse::<i64>().unwrap();
675 let err_msg = inner
676 .msg
677 .value()
678 .replace("${field}", &fname.to_string());
679 if min_value > max_value {
680 panic!("Invalid validation: min value {} is greater than max value {} for field {}", min_value, max_value, fname);
681 }
682 if min_value < 0 && max_value < 0 {
683 panic!("Invalid validation: both min and max values are negative for field {}", fname);
684 } else if min_value < 0 {
685 let max: usize = max_value.try_into().unwrap();
686 validates.push(quote! {
687 if #fname.len() > #max {
688 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
689 }
690 });
691 } else if max_value < 0 {
692 let min: usize = min_value.try_into().unwrap();
693 validates.push(quote! {
694 if #fname.len() < #min {
695 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
696 }
697 });
698 } else {
699 let min: usize = min_value.try_into().unwrap();
700 let max: usize = max_value.try_into().unwrap();
701 if field_is_option {
702 validates.push(quote! {
703 let length = match &#fname { // 使用引用
704 Some(s) => {
705 let __length = s.len();
706 if __length < #min || __length > #max {
707 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
708 }
709 },
710 None => {},
711 };
712 });
713 } else {
714 validates.push(quote! {
715 if #fname.len() > #max {
716 return Err(::afastdata_core::Error::validate(#code, #err_msg.to_string()));
717 }
718 });
719 }
720 }
721 } else if meta.path.is_ident("func") {
722 let inner = meta.parse_args::<LitStr>().unwrap();
723 let ident =
724 syn::parse_str::<syn::Ident>(&inner.value()).unwrap();
725 let field = fname.to_string();
726 validates.push(quote! {
727 match #ident(&#fname, #field) {
728 Ok(()) => {},
729 Err(e) => return Err(e.to_afastdata_error()),
730 }
731 });
732 }
733 }
734 _ => {}
735 }
736 }
737 }
738 }
739 desers.push(quote! {
740 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
741 let #fname: #ftype = __val;
742 #(#validates)*
743 offset += __new_offset;
744 });
745 }
746 let construct = quote! {
747 #name #ty_params { #(#field_names),* }
748 };
749 (construct, desers)
750 }
751 Fields::Unnamed(unnamed) => {
752 let mut desers = Vec::new();
753 let mut field_names = Vec::new();
754 for i in 0..unnamed.unnamed.len() {
755 let fname = syn::Ident::new(&format!("__f{}", i), name.span());
756 desers.push(quote! {
757 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
758 let #fname = __val;
759 offset += __new_offset;
760 });
761 field_names.push(fname);
762 }
763 let construct = quote! {
764 #name #ty_params ( #(#field_names),* )
765 };
766 (construct, desers)
767 }
768 Fields::Unit => {
769 let construct = quote! { #name #ty_params };
770 (construct, vec![])
771 }
772 }
773}