moduforge-macros-derive 0.7.0

ModuForge-RS 宏扩展模块,提供 Node 和 Mark 的派生宏
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
//! 转换器注册表模块
//!
//! 提供全局转换器注册机制,支持用户自定义转换器注册和优先级管理。
//! 遵循开闭原则,支持运行时扩展而不修改现有代码。

use once_cell::sync::Lazy;
use proc_macro2::TokenStream as TokenStream2;
use std::sync::{Arc, RwLock};
use syn::{Field, Type};
use crate::common::{MacroError, MacroResult};
use super::{
    type_converter::TypeConverter,
    builtin_converters::{get_all_builtin_converters},
};

/// 全局转换器注册表
///
/// 使用 `once_cell` 实现全局单例,确保转换器注册表在整个程序生命周期中只有一个实例。
/// 遵循单例模式,提供全局统一的转换器管理。
///
/// # 线程安全
///
/// 使用 `RwLock` 确保多线程环境下的安全访问:
/// - 读取操作可以并发进行
/// - 写入操作(注册新转换器)会独占锁
///
/// # 设计原则体现
///
/// - **单例模式**: 确保全局只有一个注册表实例
/// - **线程安全**: 支持多线程环境下的安全使用
/// - **开闭原则**: 支持运行时添加新转换器
static GLOBAL_REGISTRY: Lazy<Arc<RwLock<ConverterRegistryImpl>>> =
    Lazy::new(|| {
        let registry = ConverterRegistryImpl::new();
        Arc::new(RwLock::new(registry))
    });

/// 转换器注册表接口
///
/// 定义转换器注册表的核心接口,遵循接口隔离原则。
/// 只包含注册表相关的必要方法,不涉及具体的转换逻辑。
///
/// # 设计原则体现
///
/// - **接口隔离**: 只定义注册表相关的必要方法
/// - **单一职责**: 专门负责转换器的管理和选择
pub trait ConverterRegistry {
    /// 注册新的转换器
    ///
    /// 将转换器添加到注册表中,按优先级进行排序。
    /// 高优先级的转换器会优先被选择使用。
    ///
    /// # 参数
    ///
    /// * `converter` - 要注册的转换器
    ///
    /// # 设计原则体现
    ///
    /// - **开闭原则**: 支持扩展新的转换器而不修改现有代码
    /// - **依赖注入**: 接受任何实现了 TypeConverter 的类型
    fn register_converter(
        &mut self,
        converter: Box<dyn TypeConverter>,
    );

    /// 查找支持指定类型的转换器
    ///
    /// 根据字段类型查找合适的转换器。
    /// 返回第一个支持该类型的转换器,按优先级排序。
    ///
    /// # 参数
    ///
    /// * `field_type` - 要转换的字段类型
    ///
    /// # 返回值
    ///
    /// 如果找到支持的转换器则返回 Some,否则返回 None
    ///
    /// # 设计原则体现
    ///
    /// - **策略模式**: 根据类型选择合适的转换策略
    /// - **单一职责**: 只负责转换器查找,不执行转换
    fn find_converter_for_type(
        &self,
        field_type: &Type,
    ) -> Option<&dyn TypeConverter>;

    /// 执行字段转换
    ///
    /// 为字段查找合适的转换器并执行转换。
    /// 这是注册表的主要功能接口。
    ///
    /// # 参数
    ///
    /// * `field` - 要转换的字段
    ///
    /// # 返回值
    ///
    /// 成功时返回转换代码,失败时返回错误
    ///
    /// # 错误情况
    ///
    /// - 没有找到支持该类型的转换器
    /// - 转换过程中发生错误
    ///
    /// # 设计原则体现
    ///
    /// - **门面模式**: 提供统一的转换接口
    /// - **策略模式**: 内部选择合适的转换策略
    fn convert_field(
        &self,
        field: &Field,
    ) -> MacroResult<TokenStream2>;

    /// 获取所有注册的转换器数量
    ///
    /// 返回当前注册表中转换器的总数。
    /// 主要用于调试和测试。
    ///
    /// # 返回值
    ///
    /// 返回转换器的数量
    fn converter_count(&self) -> usize;

    /// 清空所有转换器
    ///
    /// 移除注册表中的所有转换器。
    /// 主要用于测试环境的清理。
    ///
    /// # 设计原则体现
    ///
    /// - **单一职责**: 只负责清理操作
    fn clear_converters(&mut self);

    /// 重新加载默认转换器
    ///
    /// 清空注册表并重新加载所有内置转换器。
    /// 用于重置注册表到初始状态。
    ///
    /// # 设计原则体现
    ///
    /// - **工厂模式**: 重新创建默认转换器集合
    fn reload_default_converters(&mut self);
}

/// 转换器注册表实现
///
/// ConverterRegistry 接口的具体实现。
/// 遵循单一职责原则,专门负责转换器的管理和选择逻辑。
///
/// # 内部结构
///
/// - `converters`: 存储所有注册的转换器,按优先级降序排列
///
/// # 设计原则体现
///
/// - **单一职责**: 只负责转换器管理
/// - **里氏替换**: 实现了 ConverterRegistry 接口
/// - **开闭原则**: 支持运行时添加新转换器
pub struct ConverterRegistryImpl {
    /// 转换器列表,按优先级降序排列
    ///
    /// 优先级高的转换器排在前面,查找时会优先选择。
    /// 使用 Vec 而不是 HashMap 是为了保持优先级顺序。
    converters: Vec<Box<dyn TypeConverter>>,
}

impl ConverterRegistryImpl {
    /// 创建新的转换器注册表
    ///
    /// 初始化注册表并加载所有内置转换器。
    /// 内置转换器按优先级自动排序。
    ///
    /// # 返回值
    ///
    /// 返回包含所有内置转换器的注册表实例
    ///
    /// # 初始化的转换器
    ///
    /// - NumericConverter (优先级 95)
    /// - StringConverter (优先级 90)
    /// - BooleanConverter (优先级 85)
    /// - SpecialTypeConverter (优先级 50)
    ///
    /// # 设计原则体现
    ///
    /// - **工厂模式**: 自动创建和配置内置转换器
    /// - **单一职责**: 只负责注册表的初始化
    pub fn new() -> Self {
        let mut registry = Self { converters: Vec::new() };

        // 加载所有内置转换器
        registry.load_builtin_converters();

        registry
    }

    /// 加载内置转换器
    ///
    /// 从 builtin_converters 模块获取所有内置转换器并注册。
    /// 遵循单一职责原则,专门负责内置转换器的加载。
    ///
    /// # 加载过程
    ///
    /// 1. 获取所有内置转换器
    /// 2. 按优先级排序
    /// 3. 注册到当前注册表
    ///
    /// # 设计原则体现
    ///
    /// - **单一职责**: 只负责内置转换器加载
    /// - **开闭原则**: 新增内置转换器无需修改此方法
    fn load_builtin_converters(&mut self) {
        let builtin_converters = get_all_builtin_converters();
        for converter in builtin_converters {
            self.register_converter_internal(converter);
        }
    }

    /// 内部转换器注册方法
    ///
    /// 执行实际的转换器注册逻辑,包括优先级排序。
    /// 遵循单一职责原则,专门负责转换器的插入和排序。
    ///
    /// # 参数
    ///
    /// * `converter` - 要注册的转换器
    ///
    /// # 注册逻辑
    ///
    /// 1. 查找合适的插入位置(按优先级降序)
    /// 2. 插入转换器到正确位置
    /// 3. 保持列表的优先级顺序
    ///
    /// # 设计原则体现
    ///
    /// - **单一职责**: 只负责转换器插入和排序
    /// - **开闭原则**: 支持任意类型的转换器插入
    fn register_converter_internal(
        &mut self,
        converter: Box<dyn TypeConverter>,
    ) {
        let priority = converter.priority();

        // 找到合适的插入位置(保持优先级降序)
        let insert_pos = self
            .converters
            .iter()
            .position(|c| c.priority() < priority)
            .unwrap_or(self.converters.len());

        self.converters.insert(insert_pos, converter);
    }
}

impl Default for ConverterRegistryImpl {
    /// 创建默认的转换器注册表
    ///
    /// 等同于 `ConverterRegistryImpl::new()`
    fn default() -> Self {
        Self::new()
    }
}

impl ConverterRegistry for ConverterRegistryImpl {
    fn register_converter(
        &mut self,
        converter: Box<dyn TypeConverter>,
    ) {
        self.register_converter_internal(converter);
    }

    fn find_converter_for_type(
        &self,
        field_type: &Type,
    ) -> Option<&dyn TypeConverter> {
        self.converters
            .iter()
            .find(|converter| converter.supports_type(field_type))
            .map(|boxed| boxed.as_ref())
    }

    fn convert_field(
        &self,
        field: &Field,
    ) -> MacroResult<TokenStream2> {
        // 查找支持该字段类型的转换器
        if let Some(converter) = self.find_converter_for_type(&field.ty) {
            converter.convert_field_to_json_value(field)
        } else {
            // 没有找到支持的转换器
            let type_name = crate::common::utils::extract_type_name(&field.ty);
            let field_name = field
                .ident
                .as_ref()
                .map(|i| i.to_string())
                .unwrap_or_else(|| "匿名字段".to_string());

            Err(MacroError::unsupported_field_type(
                &field_name,
                &type_name,
                field,
            ))
        }
    }

    fn converter_count(&self) -> usize {
        self.converters.len()
    }

    fn clear_converters(&mut self) {
        self.converters.clear();
    }

    fn reload_default_converters(&mut self) {
        self.clear_converters();
        self.load_builtin_converters();
    }
}

/// 全局转换器注册表管理器
///
/// 提供对全局转换器注册表的访问和管理功能。
/// 遵循门面模式,隐藏全局注册表的复杂性。
///
/// # 设计原则体现
///
/// - **门面模式**: 提供简化的全局注册表访问接口
/// - **单一职责**: 专门负责全局注册表的管理
/// - **线程安全**: 所有操作都是线程安全的
pub struct GlobalConverterRegistry;

impl GlobalConverterRegistry {
    /// 注册全局转换器
    ///
    /// 将转换器注册到全局注册表中。
    /// 这是添加自定义转换器的主要入口点。
    ///
    /// # 参数
    ///
    /// * `converter` - 要注册的转换器
    ///
    /// # 返回值
    ///
    /// 成功时返回 Ok(()),失败时返回锁定错误
    ///
    /// # 线程安全
    ///
    /// 此方法是线程安全的,可以在多线程环境中调用。
    ///
    /// # 示例
    ///
    /// ```rust
    /// use crate::converter::{converter_registry::GlobalConverterRegistry, type_converter::BuiltinTypeConverter};
    ///
    /// let custom_converter = Box::new(BuiltinTypeConverter::new());
    /// GlobalConverterRegistry::register(custom_converter).unwrap();
    /// ```
    ///
    /// # 设计原则体现
    ///
    /// - **门面模式**: 隐藏全局锁的复杂性
    /// - **开闭原则**: 支持运行时扩展转换器
    pub fn register(converter: Box<dyn TypeConverter>) -> Result<(), String> {
        match GLOBAL_REGISTRY.write() {
            Ok(mut registry) => {
                registry.register_converter(converter);
                Ok(())
            },
            Err(e) => Err(format!("无法获取注册表写锁: {e}")),
        }
    }

    /// 转换字段
    ///
    /// 使用全局注册表转换字段。
    /// 这是执行字段转换的主要入口点。
    ///
    /// # 参数
    ///
    /// * `field` - 要转换的字段
    ///
    /// # 返回值
    ///
    /// 成功时返回转换代码,失败时返回错误
    ///
    /// # 线程安全
    ///
    /// 此方法是线程安全的,多个线程可以同时执行转换。
    ///
    /// # 示例
    ///
    /// ```rust
    /// use syn::parse_quote;
    /// use crate::converter::converter_registry::GlobalConverterRegistry;
    ///
    /// let field: syn::Field = parse_quote! {
    ///     name: String
    /// };
    ///
    /// let result = GlobalConverterRegistry::convert_field(&field);
    /// assert!(result.is_ok());
    /// ```
    ///
    /// # 设计原则体现
    ///
    /// - **门面模式**: 提供统一的转换接口
    /// - **策略模式**: 内部选择合适的转换器
    pub fn convert_field(field: &Field) -> MacroResult<TokenStream2> {
        match GLOBAL_REGISTRY.read() {
            Ok(registry) => registry.convert_field(field),
            Err(e) => Err(MacroError::GenerationError {
                message: format!("无法获取注册表读锁: {e}"),
                span: None,
            }),
        }
    }

    /// 获取转换器数量
    ///
    /// 返回全局注册表中转换器的总数。
    /// 主要用于调试和监控。
    ///
    /// # 返回值
    ///
    /// 成功时返回转换器数量,失败时返回锁定错误
    ///
    /// # 设计原则体现
    ///
    /// - **门面模式**: 提供统一的状态查询接口
    pub fn converter_count() -> Result<usize, String> {
        match GLOBAL_REGISTRY.read() {
            Ok(registry) => Ok(registry.converter_count()),
            Err(e) => Err(format!("无法获取注册表读锁: {e}")),
        }
    }

    /// 清空所有转换器
    ///
    /// 移除全局注册表中的所有转换器。
    /// 主要用于测试环境的清理。
    ///
    /// # 返回值
    ///
    /// 成功时返回 Ok(()),失败时返回锁定错误
    ///
    /// # 警告
    ///
    /// 此操作会移除所有转换器,包括内置转换器。
    /// 调用后需要重新注册转换器或调用 `reload_defaults`。
    ///
    /// # 设计原则体现
    ///
    /// - **单一职责**: 只负责清理操作
    pub fn clear_all() -> Result<(), String> {
        match GLOBAL_REGISTRY.write() {
            Ok(mut registry) => {
                registry.clear_converters();
                Ok(())
            },
            Err(e) => Err(format!("无法获取注册表写锁: {e}")),
        }
    }

    /// 重新加载默认转换器
    ///
    /// 清空注册表并重新加载所有内置转换器。
    /// 用于重置注册表到初始状态。
    ///
    /// # 返回值
    ///
    /// 成功时返回 Ok(()),失败时返回锁定错误
    ///
    /// # 使用场景
    ///
    /// - 测试后的清理
    /// - 重置到初始状态
    /// - 错误恢复
    ///
    /// # 设计原则体现
    ///
    /// - **工厂模式**: 重新创建默认转换器集合
    pub fn reload_defaults() -> Result<(), String> {
        match GLOBAL_REGISTRY.write() {
            Ok(mut registry) => {
                registry.reload_default_converters();
                Ok(())
            },
            Err(e) => Err(format!("无法获取注册表写锁: {e}")),
        }
    }

    /// 检查是否支持指定类型
    ///
    /// 检查全局注册表中是否有支持指定类型的转换器。
    /// 用于提前验证类型支持性。
    ///
    /// # 参数
    ///
    /// * `field_type` - 要检查的字段类型
    ///
    /// # 返回值
    ///
    /// 成功时返回支持性结果,失败时返回锁定错误
    ///
    /// # 设计原则体现
    ///
    /// - **门面模式**: 提供统一的支持性检查接口
    pub fn supports_type(field_type: &Type) -> Result<bool, String> {
        match GLOBAL_REGISTRY.read() {
            Ok(registry) => {
                Ok(registry.find_converter_for_type(field_type).is_some())
            },
            Err(e) => Err(format!("无法获取注册表读锁: {e}")),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use syn::parse_quote;
    use crate::converter::{
        type_converter::BuiltinTypeConverter,
        builtin_converters::{StringConverter, NumericConverter},
    };

    /// 测试注册表的创建和初始化
    #[test]
    fn test_registry_creation() {
        let registry = ConverterRegistryImpl::new();

        // 应该包含所有内置转换器
        assert!(registry.converter_count() > 0);

        // 验证支持基本类型
        let string_type: Type = parse_quote! { String };
        assert!(registry.find_converter_for_type(&string_type).is_some());

        let i32_type: Type = parse_quote! { i32 };
        assert!(registry.find_converter_for_type(&i32_type).is_some());
    }

    /// 测试转换器注册
    #[test]
    fn test_converter_registration() {
        let mut registry = ConverterRegistryImpl::new();
        let initial_count = registry.converter_count();

        // 注册新的转换器
        let custom_converter = Box::new(BuiltinTypeConverter::new());
        registry.register_converter(custom_converter);

        // 验证转换器数量增加
        assert_eq!(registry.converter_count(), initial_count + 1);
    }

    /// 测试转换器优先级排序
    #[test]
    fn test_converter_priority_ordering() {
        let mut registry = ConverterRegistryImpl::new();
        registry.clear_converters();

        // 注册不同优先级的转换器
        registry.register_converter(Box::new(StringConverter::new())); // 优先级 90
        registry.register_converter(Box::new(NumericConverter::new())); // 优先级 95

        // 验证数值转换器(高优先级)被优先选择
        let i32_type: Type = parse_quote! { i32 };
        let converter = registry.find_converter_for_type(&i32_type).unwrap();
        assert_eq!(converter.name(), "NumericConverter");
    }

    /// 测试字段转换功能
    #[test]
    fn test_field_conversion() {
        let registry = ConverterRegistryImpl::new();

        // 测试字符串字段转换
        let string_field: syn::Field = parse_quote! {
            name: String
        };

        let result = registry.convert_field(&string_field);
        assert!(result.is_ok());

        let code = result.unwrap();
        let code_str = code.to_string();
        assert!(code_str.contains("serde_json::to_value"));
        assert!(code_str.contains("name"));
    }

    /// 测试不支持类型的错误处理
    #[test]
    fn test_unsupported_type_error() {
        let registry = ConverterRegistryImpl::new();

        // 测试不支持的类型
        let unsupported_field: syn::Field = parse_quote! {
            data: std::collections::BTreeMap<String, i32>
        };

        let result = registry.convert_field(&unsupported_field);
        assert!(result.is_err());

        if let Err(MacroError::UnsupportedFieldType { field_name, .. }) = result
        {
            assert_eq!(field_name, "data");
        } else {
            panic!("期望 UnsupportedFieldType 错误");
        }
    }

    /// 测试清空和重新加载功能
    #[test]
    fn test_clear_and_reload() {
        let mut registry = ConverterRegistryImpl::new();
        let initial_count = registry.converter_count();

        // 清空所有转换器
        registry.clear_converters();
        assert_eq!(registry.converter_count(), 0);

        // 重新加载默认转换器
        registry.reload_default_converters();
        assert_eq!(registry.converter_count(), initial_count);
    }

    /// 测试全局注册表功能
    #[test]
    fn test_global_registry() {
        // 获取初始转换器数量
        let initial_count = GlobalConverterRegistry::converter_count().unwrap();

        // 注册自定义转换器
        let custom_converter = Box::new(BuiltinTypeConverter::new());
        let result = GlobalConverterRegistry::register(custom_converter);
        assert!(result.is_ok());

        // 验证转换器数量增加
        let new_count = GlobalConverterRegistry::converter_count().unwrap();
        assert_eq!(new_count, initial_count + 1);

        // 测试字段转换
        let field: syn::Field = parse_quote! {
            test: String
        };

        let conversion_result = GlobalConverterRegistry::convert_field(&field);
        assert!(conversion_result.is_ok());

        // 清理:重新加载默认转换器
        GlobalConverterRegistry::reload_defaults().unwrap();
    }

    /// 测试类型支持性检查
    #[test]
    fn test_type_support_checking() {
        // 测试支持的类型
        let string_type: Type = parse_quote! { String };
        let supports_string =
            GlobalConverterRegistry::supports_type(&string_type).unwrap();
        assert!(supports_string);

        let i32_type: Type = parse_quote! { i32 };
        let supports_i32 =
            GlobalConverterRegistry::supports_type(&i32_type).unwrap();
        assert!(supports_i32);

        // 测试不支持的类型
        let unsupported_type: Type =
            parse_quote! { std::collections::BTreeSet<String> };
        let supports_unsupported =
            GlobalConverterRegistry::supports_type(&unsupported_type).unwrap();
        assert!(!supports_unsupported);
    }

    /// 测试注册表默认构造器
    #[test]
    fn test_registry_default() {
        let registry = ConverterRegistryImpl::default();
        assert!(registry.converter_count() > 0);
    }

    /// 测试转换器查找的准确性
    #[test]
    fn test_converter_finding_accuracy() {
        let registry = ConverterRegistryImpl::new();

        // 测试各种类型的转换器查找
        let test_cases = vec![
            (parse_quote! { String }, "StringConverter"),
            (parse_quote! { i32 }, "NumericConverter"),
            (parse_quote! { bool }, "BooleanConverter"),
        ];

        for (ty, _expected_name) in test_cases {
            if let Some(converter) = registry.find_converter_for_type(&ty) {
                // 注意:由于优先级排序,实际选择的转换器可能是 BuiltinTypeConverter
                // 而不是专门的转换器,这是正常的行为
                assert!(
                    converter.supports_type(&ty),
                    "找到的转换器应该支持该类型"
                );
            } else {
                panic!("应该能找到支持 {ty:?} 的转换器");
            }
        }
    }
}