rust_patterns/builder.rs
1/// 为构建器模式提供辅助方法的宏。
2///
3/// 此宏为指定的构建器类型添加一个 `when_some` 方法,允许条件性地设置可选值。
4/// 当 `Option<T>` 为 `Some` 时,会调用提供的函数来设置值;当为 `None` 时,直接返回构建器本身。
5///
6/// # 用法
7///
8/// 有两种调用方式:
9/// 1. 为 `Self` 类型实现:
10/// ```rust
11/// use rust_patterns::builder_helper;
12///
13/// struct MyBuilder1;
14/// struct MyBuilder2;
15///
16/// builder_helper!(Self, MyBuilder1, MyBuilder2);
17///
18/// // 现在 MyBuilder1 和 MyBuilder2 都有 when_some 方法
19/// ```
20/// 2. 为 `&mut Self` 类型实现:
21/// ```rust
22/// use rust_patterns::builder_helper;
23///
24/// struct MyBuilder1;
25/// struct MyBuilder2;
26///
27/// builder_helper!(&mut Self, MyBuilder1, MyBuilder2);
28///
29/// // 现在 MyBuilder1 和 MyBuilder2 都有 when_some 方法
30/// ```
31///
32/// # 生成的方法
33///
34/// 宏会为每个指定的构建器类型生成一个 `when_some` 方法:
35/// ```rust
36/// # use rust_patterns::builder_helper;
37/// # struct MyBuilder;
38/// # builder_helper!(Self, MyBuilder);
39/// # impl MyBuilder {
40/// fn when_some<T>(self, value: Option<T>, func: impl FnOnce(Self, T) -> Self) -> Self
41/// where
42/// Self: Sized;
43/// # }
44/// ```
45///
46/// 或者对于 `&mut Self` 版本:
47/// ```rust
48/// # use rust_patterns::builder_helper;
49/// # struct MyBuilder;
50/// # builder_helper!(&mut Self, MyBuilder);
51/// # impl MyBuilder {
52/// fn when_some<T>(&mut self, value: Option<T>, func: impl FnOnce(&mut Self, T) -> &mut Self) -> &mut Self
53/// where
54/// Self: Sized;
55/// # }
56/// ```
57#[macro_export]
58macro_rules! builder_helper {
59 (@ { $self:ty, $($builder:ty),+ }) => {
60 /// 构建器辅助 trait,提供条件性设置值的方法。
61 trait Builder {
62 #[inline]
63 fn when_some<T>(self: $self, value: Option<T>, func: impl FnOnce($self, T) -> $self) -> $self
64 where
65 Self: Sized,
66 {
67 match value {
68 Some(v) => func(self, v),
69 None => self,
70 }
71 }
72 }
73
74 $(impl Builder for $builder {})+
75 };
76
77 (Self, $($builder:ty),+ $(,)?) => {
78 $crate::builder_helper!(@ {Self, $($builder),+});
79 };
80
81 (&mut Self, $($builder:ty),+ $(,)?) => {
82 $crate::builder_helper!(@ {&mut Self, $($builder),+});
83 };
84}