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::{parse_macro_input, Data, DeriveInput, Fields, Index};
76
77/// 为结构体或枚举生成 [`AFastSerialize`] trait 实现。
78///
79/// Generates an [`AFastSerialize`] trait implementation for a struct or enum.
80///
81/// # 生成的代码 / Generated Code
82///
83/// ## 结构体 / Struct
84///
85/// 为每个字段调用 `to_bytes()`,并将结果依次追加到字节缓冲区中。
86///
87/// Calls `to_bytes()` on each field, appending the results to a byte buffer
88/// sequentially.
89///
90/// ```ignore
91/// // 以下为生成代码的示意(非实际代码)
92/// // The following is an illustration of generated code (not actual code)
93/// impl AFastSerialize for MyStruct {
94/// fn to_bytes(&self) -> Vec<u8> {
95/// let mut bytes = Vec::new();
96/// bytes.extend(AFastSerialize::to_bytes(&self.field1));
97/// bytes.extend(AFastSerialize::to_bytes(&self.field2));
98/// // ...
99/// bytes
100/// }
101/// }
102/// ```
103///
104/// ## 枚举 / Enum
105///
106/// 先写入 `u32` 变体索引(从 0 开始),再写入变体的字段数据。
107/// Unit 变体只写入索引。
108///
109/// Writes a `u32` variant index (starting from 0), then the variant's field data.
110/// Unit variants only write the index.
111///
112/// ```ignore
113/// // 以下为生成代码的示意(非实际代码)
114/// // The following is an illustration of generated code (not actual code)
115/// impl AFastSerialize for MyEnum {
116/// fn to_bytes(&self) -> Vec<u8> {
117/// let mut bytes = Vec::new();
118/// match self {
119/// MyEnum::Variant1 => {
120/// bytes.extend(0u32.to_le_bytes());
121/// }
122/// MyEnum::Variant2(field) => {
123/// bytes.extend(1u32.to_le_bytes());
124/// bytes.extend(AFastSerialize::to_bytes(field));
125/// }
126/// // ...
127/// }
128/// bytes
129/// }
130/// }
131/// ```
132///
133/// # 泛型 / Generics
134///
135/// 如果目标类型包含泛型参数,生成的 `impl` 会自动为这些参数添加
136/// `AFastSerialize` 约束。
137///
138/// If the target type contains generic parameters, the generated `impl` automatically
139/// adds `AFastSerialize` bounds to those parameters.
140///
141/// # Panics
142///
143/// 对 union 类型使用此宏会触发编译 panic。
144///
145/// Using this macro on a union type will trigger a compile-time panic.
146#[proc_macro_derive(AFastSerialize)]
147pub fn derive_serialize(input: TokenStream) -> TokenStream {
148 let input = parse_macro_input!(input as DeriveInput);
149 let name = &input.ident;
150 let generics = &input.generics;
151
152 // 为泛型参数添加 AFastSerialize trait 约束
153 // Add AFastSerialize trait bounds to generic parameters
154 let mut generics_with_bounds = generics.clone();
155 for param in &mut generics_with_bounds.params {
156 if let syn::GenericParam::Type(ref mut ty) = *param {
157 ty.bounds.push(syn::parse_quote!(::afastdata_core::AFastSerialize));
158 }
159 }
160 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
161 let (_, ty_generics, _) = generics.split_for_impl();
162
163 let expanded = match &input.data {
164 Data::Struct(data) => {
165 let serialize_body = generate_serialize_fields(&data.fields, quote!(self));
166 quote! {
167 impl #impl_generics ::afastdata_core::AFastSerialize for #name #ty_generics {
168 fn to_bytes(&self) -> Vec<u8> {
169 let mut bytes = Vec::new();
170 #(#serialize_body)*
171 bytes
172 }
173 }
174 }
175 }
176 Data::Enum(data) => {
177 let mut arms = Vec::new();
178 for (i, variant) in data.variants.iter().enumerate() {
179 let variant_name = &variant.ident;
180 let tag = i as u32;
181
182 match &variant.fields {
183 Fields::Unit => {
184 // Unit 变体:只写入 u32 索引
185 // Unit variant: write only the u32 index
186 arms.push(quote! {
187 #name::#variant_name => {
188 bytes.extend(#tag.to_le_bytes());
189 }
190 });
191 }
192 Fields::Unnamed(fields) => {
193 // 元组变体:写入 u32 索引 + 逐字段序列化
194 // Tuple variant: write u32 index + field-by-field serialization
195 let field_names: Vec<_> = (0..fields.unnamed.len())
196 .map(|i| {
197 let ident = syn::Ident::new(&format!("__f{}", i), variant_name.span());
198 ident
199 })
200 .collect();
201 let field_patterns = &field_names;
202 let mut serialize_fields = Vec::new();
203 for fname in &field_names {
204 serialize_fields.push(quote! {
205 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(#fname));
206 });
207 }
208 arms.push(quote! {
209 #name::#variant_name(#(#field_patterns),*) => {
210 bytes.extend(#tag.to_le_bytes());
211 #(#serialize_fields)*
212 }
213 });
214 }
215 Fields::Named(fields) => {
216 // 命名字段变体:写入 u32 索引 + 逐字段序列化
217 // Named-field variant: write u32 index + field-by-field serialization
218 let field_names: Vec<_> =
219 fields.named.iter().map(|f| f.ident.as_ref().unwrap()).collect();
220 let mut serialize_fields = Vec::new();
221 for fname in &field_names {
222 serialize_fields.push(quote! {
223 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(#fname));
224 });
225 }
226 arms.push(quote! {
227 #name::#variant_name { #(#field_names),* } => {
228 bytes.extend(#tag.to_le_bytes());
229 #(#serialize_fields)*
230 }
231 });
232 }
233 }
234 }
235
236 quote! {
237 impl #impl_generics ::afastdata_core::AFastSerialize for #name #ty_generics {
238 fn to_bytes(&self) -> Vec<u8> {
239 let mut bytes = Vec::new();
240 match self {
241 #(#arms)*
242 }
243 bytes
244 }
245 }
246 }
247 }
248 Data::Union(_) => panic!("AFastSerialize does not support unions"),
249 };
250
251 TokenStream::from(expanded)
252}
253
254/// 为结构体或枚举生成 [`AFastDeserialize`] trait 实现。
255///
256/// Generates an [`AFastDeserialize`] trait implementation for a struct or enum.
257///
258/// # 生成的代码 / Generated Code
259///
260/// ## 结构体 / Struct
261///
262/// 为每个字段依次调用 `from_bytes()`,并使用偏移量追踪已消耗的字节数,
263/// 最后构造结构体实例。
264///
265/// Calls `from_bytes()` on each field sequentially, using an offset to track
266/// consumed bytes, then constructs the struct instance.
267///
268/// ```ignore
269/// // 以下为生成代码的示意(非实际代码)
270/// // The following is an illustration of generated code (not actual code)
271/// impl AFastDeserialize for MyStruct {
272/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), String> {
273/// let mut offset: usize = 0;
274/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
275/// let field1 = __val;
276/// offset += __new_offset;
277/// // ... 更多字段 / more fields ...
278/// Ok((MyStruct { field1, ... }, offset))
279/// }
280/// }
281/// ```
282///
283/// ## 枚举 / Enum
284///
285/// 先读取 `u32` 变体索引,根据索引匹配对应变体,再反序列化该变体的字段。
286///
287/// First reads the `u32` variant index, matches the corresponding variant by index,
288/// then deserializes the variant's fields.
289///
290/// ```ignore
291/// // 以下为生成代码的示意(非实际代码)
292/// // The following is an illustration of generated code (not actual code)
293/// impl AFastDeserialize for MyEnum {
294/// fn from_bytes(data: &[u8]) -> Result<(Self, usize), String> {
295/// let mut offset: usize = 0;
296/// let (__tag, __new_offset) = <u32 as AFastDeserialize>::from_bytes(&data[offset..])?;
297/// offset += __new_offset;
298/// match __tag {
299/// 0 => Ok((MyEnum::Variant1, offset)),
300/// 1 => {
301/// let (__val, __new_offset) = AFastDeserialize::from_bytes(&data[offset..])?;
302/// offset += __new_offset;
303/// Ok((MyEnum::Variant2(__val), offset))
304/// }
305/// v => Err(format!("Unknown variant tag: {} for MyEnum", v)),
306/// }
307/// }
308/// }
309/// ```
310///
311/// # 泛型 / Generics
312///
313/// 如果目标类型包含泛型参数,生成的 `impl` 会同时添加 `AFastSerialize` 和
314/// `AFastDeserialize` 约束。双重约束确保泛型类型在序列化和反序列化两个方向
315/// 上都可用。
316///
317/// If the target type contains generic parameters, the generated `impl` adds both
318/// `AFastSerialize` and `AFastDeserialize` bounds. The dual bounds ensure the generic
319/// type is available in both serialization and deserialization directions.
320///
321/// # Panics
322///
323/// 对 union 类型使用此宏会触发编译 panic。
324///
325/// Using this macro on a union type will trigger a compile-time panic.
326#[proc_macro_derive(AFastDeserialize)]
327pub fn derive_deserialize(input: TokenStream) -> TokenStream {
328 let input = parse_macro_input!(input as DeriveInput);
329 let name = &input.ident;
330 let generics = &input.generics;
331
332 // 为泛型参数添加 AFastSerialize + AFastDeserialize trait 约束
333 // Add AFastSerialize + AFastDeserialize trait bounds to generic parameters
334 let mut generics_with_bounds = generics.clone();
335 for param in &mut generics_with_bounds.params {
336 if let syn::GenericParam::Type(ref mut ty) = *param {
337 ty.bounds.push(syn::parse_quote!(::afastdata_core::AFastSerialize));
338 ty.bounds.push(syn::parse_quote!(::afastdata_core::AFastDeserialize));
339 }
340 }
341 let (impl_generics, _, _) = generics_with_bounds.split_for_impl();
342 let (_, ty_generics, _) = generics.split_for_impl();
343
344 let expanded = match &input.data {
345 Data::Struct(data) => {
346 let (construct, field_desers) =
347 generate_deserialize_fields(&data.fields, &name, &ty_generics);
348 quote! {
349 impl #impl_generics ::afastdata_core::AFastDeserialize for #name #ty_generics {
350 fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::std::string::String> {
351 let mut offset: usize = 0;
352 #(#field_desers)*
353 Ok((#construct, offset))
354 }
355 }
356 }
357 }
358 Data::Enum(data) => {
359 let mut arms = Vec::new();
360 for (i, variant) in data.variants.iter().enumerate() {
361 let variant_name = &variant.ident;
362 let tag = i as u32;
363
364 match &variant.fields {
365 Fields::Unit => {
366 // Unit 变体:匹配索引后直接返回
367 // Unit variant: match index and return directly
368 arms.push(quote! {
369 #tag => {
370 Ok((#name::#variant_name, offset))
371 }
372 });
373 }
374 Fields::Unnamed(fields) => {
375 // 元组变体:匹配索引后逐字段反序列化
376 // Tuple variant: match index, then deserialize fields sequentially
377 let mut field_desers = Vec::new();
378 let mut field_names = Vec::new();
379 for _ in &fields.unnamed {
380 let fname = syn::Ident::new(
381 &format!("__f{}", field_names.len()),
382 variant_name.span(),
383 );
384 field_desers.push(quote! {
385 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
386 let #fname = __val;
387 offset += __new_offset;
388 });
389 field_names.push(fname);
390 }
391 arms.push(quote! {
392 #tag => {
393 #(#field_desers)*
394 Ok((#name::#variant_name(#(#field_names),*), offset))
395 }
396 });
397 }
398 Fields::Named(fields) => {
399 // 命名字段变体:匹配索引后逐字段反序列化
400 // Named-field variant: match index, then deserialize fields sequentially
401 let mut field_desers = Vec::new();
402 let mut field_names = Vec::new();
403 for f in &fields.named {
404 let fname = f.ident.as_ref().unwrap();
405 field_desers.push(quote! {
406 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
407 let #fname = __val;
408 offset += __new_offset;
409 });
410 field_names.push(fname);
411 }
412 arms.push(quote! {
413 #tag => {
414 #(#field_desers)*
415 Ok((#name::#variant_name { #(#field_names),* }, offset))
416 }
417 });
418 }
419 }
420 }
421
422 quote! {
423 impl #impl_generics ::afastdata_core::AFastDeserialize for #name #ty_generics {
424 fn from_bytes(data: &[u8]) -> Result<(Self, usize), ::std::string::String> {
425 let mut offset: usize = 0;
426 // 读取 u32 变体索引
427 // Read the u32 variant index
428 let (__tag_bytes, __new_offset) = <u32 as ::afastdata_core::AFastDeserialize>::from_bytes(&data[offset..])?;
429 offset += __new_offset;
430 match __tag_bytes {
431 #(#arms)*
432 v => Err(::std::format!("Unknown variant tag: {} for {}", v, ::std::stringify!(#name))),
433 }
434 }
435 }
436 }
437 }
438 Data::Union(_) => panic!("AFastDeserialize does not support unions"),
439 };
440
441 TokenStream::from(expanded)
442}
443
444/// 为结构体的字段生成序列化代码。内部辅助函数。
445///
446/// Generates serialization code for struct fields. Internal helper.
447///
448/// # 参数 / Parameters
449///
450/// - `fields`:结构体的字段定义 / The struct's field definitions
451/// - `self_prefix`:访问字段时使用的前缀(如 `self` 或变体解构变量)
452/// / The prefix used to access fields (e.g., `self` or a variant destructure variable)
453///
454/// # 返回值 / Returns
455///
456/// 返回一个 `TokenStream` 列表,每个元素对应一个字段的序列化语句。
457///
458/// Returns a list of `TokenStream`s, each corresponding to a serialization statement
459/// for one field.
460///
461/// # 生成格式 / Generated Format
462///
463/// - **命名字段 (Named)**:`bytes.extend(AFastSerialize::to_bytes(&self.field_name));`
464/// - **元组字段 (Unnamed)**:`bytes.extend(AFastSerialize::to_bytes(&self.0));`
465/// - **单元字段 (Unit)**:不生成任何代码 / Generates no code
466fn generate_serialize_fields(
467 fields: &Fields,
468 self_prefix: proc_macro2::TokenStream,
469) -> Vec<proc_macro2::TokenStream> {
470 match fields {
471 Fields::Named(named) => named
472 .named
473 .iter()
474 .map(|f| {
475 let fname = f.ident.as_ref().unwrap();
476 quote! {
477 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(&#self_prefix.#fname));
478 }
479 })
480 .collect(),
481 Fields::Unnamed(unnamed) => unnamed
482 .unnamed
483 .iter()
484 .enumerate()
485 .map(|(i, _)| {
486 let idx = Index::from(i);
487 quote! {
488 bytes.extend(::afastdata_core::AFastSerialize::to_bytes(&#self_prefix.#idx));
489 }
490 })
491 .collect(),
492 Fields::Unit => vec![],
493 }
494}
495
496/// 为结构体的字段生成反序列化代码以及构造表达式。内部辅助函数。
497///
498/// Generates deserialization code for struct fields along with the construction
499/// expression. Internal helper.
500///
501/// # 参数 / Parameters
502///
503/// - `fields`:结构体的字段定义 / The struct's field definitions
504/// - `name`:结构体类型的标识符 / The struct type's identifier
505/// - `ty_generics`:类型的泛型参数(用于构造时的 turbofish 语法)
506/// / The type's generic parameters (used for turbofish syntax during construction)
507///
508/// # 返回值 / Returns
509///
510/// 返回 `(构造表达式, 反序列化语句列表)`:
511/// - 构造表达式:用于创建结构体实例的 `TokenStream`
512/// - 反序列化语句:每个字段的 `from_bytes()` 调用和偏移量更新
513///
514/// Returns `(construction_expression, deserialization_statements)`:
515/// - Construction expression: A `TokenStream` for creating the struct instance
516/// - Deserialization statements: `from_bytes()` calls and offset updates for each field
517///
518/// # 泛型构造 / Generic Construction
519///
520/// 使用 `as_turbofish()` 生成正确的泛型语法。例如 `MyStruct::<T>` 而非
521/// `MyStruct <T>`(后者会被解析为比较操作)。
522///
523/// Uses `as_turbofish()` to generate correct generic syntax. For example,
524/// `MyStruct::<T>` instead of `MyStruct <T>` (which would be parsed as a
525/// comparison operation).
526fn generate_deserialize_fields(
527 fields: &Fields,
528 name: &syn::Ident,
529 ty_generics: &syn::TypeGenerics,
530) -> (proc_macro2::TokenStream, Vec<proc_macro2::TokenStream>) {
531 // 在表达式上下文中使用 turbofish 语法:Name::<T>
532 // In expression context, use turbofish syntax: Name::<T>
533 let ty_params = ty_generics.as_turbofish();
534 match fields {
535 Fields::Named(named) => {
536 let mut desers = Vec::new();
537 let mut field_names = Vec::new();
538 for f in &named.named {
539 let fname = f.ident.as_ref().unwrap();
540 field_names.push(fname.clone());
541 desers.push(quote! {
542 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
543 let #fname = __val;
544 offset += __new_offset;
545 });
546 }
547 let construct = quote! {
548 #name #ty_params { #(#field_names),* }
549 };
550 (construct, desers)
551 }
552 Fields::Unnamed(unnamed) => {
553 let mut desers = Vec::new();
554 let mut field_names = Vec::new();
555 for i in 0..unnamed.unnamed.len() {
556 let fname = syn::Ident::new(&format!("__f{}", i), name.span());
557 desers.push(quote! {
558 let (__val, __new_offset) = ::afastdata_core::AFastDeserialize::from_bytes(&data[offset..])?;
559 let #fname = __val;
560 offset += __new_offset;
561 });
562 field_names.push(fname);
563 }
564 let construct = quote! {
565 #name #ty_params ( #(#field_names),* )
566 };
567 (construct, desers)
568 }
569 Fields::Unit => {
570 let construct = quote! { #name #ty_params };
571 (construct, vec![])
572 }
573 }
574}