Skip to main content

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}