Skip to main content

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}