1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//! Provider for any remote object.

#[cfg(feature = "rfn")]
use crate::rfn;

#[cfg(feature = "robj")]
use crate::robj;

/// A provider for any remote object.
///
/// This helps to store providers of different remote object types together.
/// For example, you can keep providers of different types in a single vector.
///
/// Dropping the provider will stop making the object available remotely.
#[cfg_attr(docsrs, doc(cfg(any(feature = "rfn", feature = "robj"))))]
#[derive(Debug)]
#[non_exhaustive]
pub enum Provider {
    /// A provider for [RFn](rfn::RFn).
    #[cfg(feature = "rfn")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rfn")))]
    RFn(rfn::RFnProvider),
    /// A provider for [RFnMut](rfn::RFnMut).
    #[cfg(feature = "rfn")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rfn")))]
    RFnMut(rfn::RFnMutProvider),
    /// A provider for [RFnOnce](rfn::RFnOnce).
    #[cfg(feature = "rfn")]
    #[cfg_attr(docsrs, doc(cfg(feature = "rfn")))]
    RFnOnce(rfn::RFnOnceProvider),
    /// A provider for [Handle](robj::handle::Handle).
    #[cfg(feature = "robj")]
    #[cfg_attr(docsrs, doc(cfg(feature = "robj")))]
    Handle(robj::handle::Provider),
    /// A provider for [Lazy](robj::lazy::Lazy).
    #[cfg(feature = "robj")]
    #[cfg_attr(docsrs, doc(cfg(feature = "robj")))]
    Lazy(robj::lazy::Provider),
    /// A provider for [LazyBlob](robj::lazy_blob::LazyBlob).
    #[cfg(feature = "robj")]
    #[cfg_attr(docsrs, doc(cfg(feature = "robj")))]
    LazyBlob(robj::lazy_blob::Provider),
}

#[cfg(feature = "rfn")]
impl From<rfn::RFnProvider> for Provider {
    fn from(provider: rfn::RFnProvider) -> Self {
        Self::RFn(provider)
    }
}

#[cfg(feature = "rfn")]
impl From<rfn::RFnMutProvider> for Provider {
    fn from(provider: rfn::RFnMutProvider) -> Self {
        Self::RFnMut(provider)
    }
}

#[cfg(feature = "rfn")]
impl From<rfn::RFnOnceProvider> for Provider {
    fn from(provider: rfn::RFnOnceProvider) -> Self {
        Self::RFnOnce(provider)
    }
}

#[cfg(feature = "robj")]
impl From<robj::handle::Provider> for Provider {
    fn from(provider: robj::handle::Provider) -> Self {
        Self::Handle(provider)
    }
}

#[cfg(feature = "robj")]
impl From<robj::lazy::Provider> for Provider {
    fn from(provider: robj::lazy::Provider) -> Self {
        Self::Lazy(provider)
    }
}

#[cfg(feature = "robj")]
impl From<robj::lazy_blob::Provider> for Provider {
    fn from(provider: robj::lazy_blob::Provider) -> Self {
        Self::LazyBlob(provider)
    }
}

impl Provider {
    /// Releases the provider while keeping the remote object alive
    /// until it is dropped.
    pub fn keep(self) {
        match self {
            #[cfg(feature = "rfn")]
            Self::RFn(provider) => provider.keep(),
            #[cfg(feature = "rfn")]
            Self::RFnMut(provider) => provider.keep(),
            #[cfg(feature = "rfn")]
            Self::RFnOnce(provider) => provider.keep(),
            #[cfg(feature = "robj")]
            Self::Handle(provider) => provider.keep(),
            #[cfg(feature = "robj")]
            Self::Lazy(provider) => provider.keep(),
            #[cfg(feature = "robj")]
            Self::LazyBlob(provider) => provider.keep(),
        }
    }

    /// Waits until the provider can be safely dropped because it is not
    /// needed anymore.
    pub async fn done(&mut self) {
        match self {
            #[cfg(feature = "rfn")]
            Self::RFn(provider) => provider.done().await,
            #[cfg(feature = "rfn")]
            Self::RFnMut(provider) => provider.done().await,
            #[cfg(feature = "rfn")]
            Self::RFnOnce(provider) => provider.done().await,
            #[cfg(feature = "robj")]
            Self::Handle(provider) => provider.done().await,
            #[cfg(feature = "robj")]
            Self::Lazy(provider) => provider.done().await,
            #[cfg(feature = "robj")]
            Self::LazyBlob(provider) => provider.done().await,
        }
    }
}