rx_rust/disposable/delegate_disposal.rs
1/// Defines a named disposal type that delegates [`Disposable::dispose`] to an
2/// inner disposal value.
3///
4/// This macro is specifically intended to put a short, stable name in front of
5/// a disposal type with two or more nested type-wrapper layers. Count layers
6/// along the deepest path through the type: `Outer<D>` has one layer, while
7/// `Outer<Inner<D>>` has two. Use this macro for the latter and for deeper
8/// compositions. Every instantiated concrete generic type counts as a layer;
9/// for example, `OptionDisposal<ConcreteDisposal<'a, T>>` has two layers.
10///
11/// Do not use this macro for a disposal type with only one wrapper layer. Write
12/// and return that concrete type directly instead.
13///
14/// The generated type implements [`Disposable`] by forwarding to the inner
15/// value. It also implements conversion from the inner value to the generated
16/// type. Use [`DisposableExt::into_subscription`] to convert the inner value
17/// directly into a [`Subscription`] of the generated type.
18///
19/// [`Disposable`]: crate::disposable::Disposable
20/// [`Disposable::dispose`]: crate::disposable::Disposable::dispose
21/// [`DisposableExt::into_subscription`]: crate::disposable::DisposableExt::into_subscription
22/// [`Subscription`]: crate::observable::Subscription
23#[macro_export]
24macro_rules! delegate_disposal {
25 (
26 $(#[$meta:meta])*
27 $name:ident<$($generic:tt),+ $(,)?>,
28 $inner:ty $(,)?
29 where $($where_clause:tt)+
30 ) => {
31 $crate::delegate_disposal! {
32 @impl
33 [$(#[$meta])*]
34 [$name]
35 [$($generic),+]
36 [$inner]
37 [where $($where_clause)+]
38 [, $($where_clause)+]
39 }
40 };
41
42 (
43 $(#[$meta:meta])*
44 $name:ident<$($generic:tt),+ $(,)?>,
45 $inner:ty
46 $(,)?
47 ) => {
48 $crate::delegate_disposal! {
49 @impl
50 [$(#[$meta])*]
51 [$name]
52 [$($generic),+]
53 [$inner]
54 []
55 []
56 }
57 };
58
59 (
60 @impl
61 [$($meta:tt)*]
62 [$name:ident]
63 [$($generic:tt),+]
64 [$inner:ty]
65 [$($struct_where:tt)*]
66 [$($where_clause:tt)*]
67 ) => {
68 $($meta)*
69 pub struct $name<$($generic),+>($inner) $($struct_where)*;
70
71 impl<$($generic),+> $crate::disposable::Disposable for $name<$($generic),+>
72 where
73 $inner: $crate::disposable::Disposable
74 $($where_clause)*
75 {
76 fn dispose(self) {
77 self.0.dispose();
78 }
79 }
80
81 impl<$($generic),+> From<$inner>
82 for $name<$($generic),+>
83 $($struct_where)*
84 {
85 fn from(value: $inner) -> Self {
86 Self(value)
87 }
88 }
89 };
90}