Skip to main content

rx_rust/disposable/
boxed_disposal.rs

1use crate::{disposable::Disposable, utils::types::MaybeSend};
2
3trait ErasedDisposable {
4    fn dispose_boxed(self: Box<Self>);
5}
6
7impl<D> ErasedDisposable for D
8where
9    D: Disposable,
10{
11    fn dispose_boxed(self: Box<Self>) {
12        Disposable::dispose(*self);
13    }
14}
15
16cfg_if::cfg_if! {
17    if #[cfg(feature = "single-threaded")] {
18        /// Type-erased disposal for single-threaded builds to handle this problem <https://stackoverflow.com/q/46620790/9315497>
19        pub struct BoxedDisposal<'dis>(Box<dyn ErasedDisposable + 'dis>);
20    } else {
21        /// Type-erased disposal for multi-threaded builds to handle this problem <https://stackoverflow.com/q/46620790/9315497>
22        pub struct BoxedDisposal<'dis>(Box<dyn ErasedDisposable + Send + 'dis>);
23    }
24}
25
26impl<'dis> BoxedDisposal<'dis> {
27    pub fn new(disposal: impl Disposable + MaybeSend + 'dis) -> Self {
28        Self(Box::new(disposal))
29    }
30}
31
32impl Disposable for BoxedDisposal<'_> {
33    #[inline]
34    fn dispose(self) {
35        self.0.dispose_boxed();
36    }
37}
38
39impl std::fmt::Debug for BoxedDisposal<'_> {
40    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41        f.write_str(std::any::type_name::<Self>())
42    }
43}