Skip to main content

rx_rust/disposable/
bound_drop_disposal.rs

1use crate::disposable::{Disposable, chain_disposal::ChainDisposal};
2use educe::Educe;
3
4/// A disposal that calls the `dispose` method of a `Disposable` when dropped.
5#[must_use = "dropping this disposal immediately dispose the inner disposable"]
6#[derive(Educe)]
7#[educe(Debug)]
8pub struct BoundDropDisposal<D: Disposable>(Option<D>);
9
10impl<D: Disposable> BoundDropDisposal<D> {
11    pub fn new(disposal: D) -> Self {
12        Self(Some(disposal))
13    }
14
15    pub fn preceded_by<D0: Disposable>(self, other: D0) -> BoundDropDisposal<ChainDisposal<D0, D>> {
16        BoundDropDisposal::new(ChainDisposal::new(other, self.into_inner()))
17    }
18
19    pub fn then<D1: Disposable>(self, other: D1) -> BoundDropDisposal<ChainDisposal<D, D1>> {
20        BoundDropDisposal::new(ChainDisposal::new(self.into_inner(), other))
21    }
22
23    pub fn preceded_by_bound<D1: Disposable>(
24        self,
25        other: BoundDropDisposal<D1>,
26    ) -> BoundDropDisposal<ChainDisposal<D1, D>> {
27        BoundDropDisposal::new(ChainDisposal::new(other.into_inner(), self.into_inner()))
28    }
29
30    pub fn map_into<D1>(self) -> BoundDropDisposal<D1>
31    where
32        D1: From<D> + Disposable,
33    {
34        BoundDropDisposal::new(self.into_inner().into())
35    }
36
37    // Private for safety
38    fn into_inner(mut self) -> D {
39        self.0.take().unwrap()
40    }
41}
42
43impl Default for BoundDropDisposal<()> {
44    fn default() -> Self {
45        Self::new(())
46    }
47}
48
49impl<D: Disposable> Disposable for BoundDropDisposal<D> {
50    fn dispose(self) {
51        // Drop to call the dispose
52    }
53}
54
55impl<D: Disposable> Drop for BoundDropDisposal<D> {
56    fn drop(&mut self) {
57        if let Some(disposal) = self.0.take() {
58            disposal.dispose();
59        }
60    }
61}