Skip to main content

beekeeper/bee/
queen.rs

1//! The Queen bee trait.
2use super::Worker;
3use derive_more::Debug;
4use parking_lot::RwLock;
5use std::marker::PhantomData;
6use std::ops::Deref;
7use std::{any, fmt};
8
9/// A trait for factories that create `Worker`s.
10pub trait Queen: Send + Sync + 'static {
11    /// The kind of `Worker` created by this factory.
12    type Kind: Worker;
13
14    /// Creates and returns a new instance of `Self::Kind`, *immutably*.
15    fn create(&self) -> Self::Kind;
16}
17
18/// A trait for mutable factories that create `Worker`s.
19pub trait QueenMut: Send + Sync + 'static {
20    /// The kind of `Worker` created by this factory.
21    type Kind: Worker;
22
23    /// Creates and returns a new instance of `Self::Kind`, *immutably*.
24    fn create(&mut self) -> Self::Kind;
25}
26
27/// A wrapper for a `MutQueen` that implements `Queen`.
28///
29/// Interior mutability is enabled using an `RwLock`.
30pub struct QueenCell<Q: QueenMut>(RwLock<Q>);
31
32impl<Q: QueenMut> QueenCell<Q> {
33    /// Creates a new `QueenCell` with the given `mut_queen`.
34    pub fn new(mut_queen: Q) -> Self {
35        Self(RwLock::new(mut_queen))
36    }
37
38    /// Returns a reference to the wrapped `Queen`.
39    pub fn get(&self) -> impl Deref<Target = Q> {
40        self.0.read()
41    }
42
43    /// Consumes this `QueenCell` and returns the inner `Queen`.
44    pub fn into_inner(self) -> Q {
45        self.0.into_inner()
46    }
47}
48
49impl<Q: QueenMut> Queen for QueenCell<Q> {
50    type Kind = Q::Kind;
51
52    /// Calls the wrapped `QueenMut::create` method using interior mutability.
53    fn create(&self) -> Self::Kind {
54        self.0.write().create()
55    }
56}
57
58impl<Q: QueenMut + fmt::Debug> fmt::Debug for QueenCell<Q> {
59    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60        f.debug_struct("QueenCell")
61            .field("queen", &*self.0.read())
62            .finish()
63    }
64}
65
66impl<Q: QueenMut + Clone> Clone for QueenCell<Q> {
67    fn clone(&self) -> Self {
68        Self(RwLock::new(self.0.read().clone()))
69    }
70}
71
72impl<Q: QueenMut + Default> Default for QueenCell<Q> {
73    fn default() -> Self {
74        Self::new(Q::default())
75    }
76}
77
78impl<Q: QueenMut> From<Q> for QueenCell<Q> {
79    fn from(queen: Q) -> Self {
80        Self::new(queen)
81    }
82}
83
84/// A `Queen` that can create a `Worker` type that implements `Default`.
85///
86/// Note that, for the implementation to be generic, `W` also needs to be `Send` and `Sync`. If you
87/// want a `Queen` for a specific `Worker` type that is not `Send/Sync`:
88///
89/// ```
90/// # use beekeeper::bee::{Context, Queen, Worker, WorkerResult};
91/// # use std::rc::Rc;
92///
93/// #[derive(Default, Debug)]
94/// struct MyWorker(Rc<u8>); // not `Send` or `Sync`
95///
96/// impl Worker for MyWorker {
97///     type Input = u8;
98///     type Output = u8;
99///     type Error = ();
100///
101///     fn apply(&mut self, input: u8, _: &Context<Self::Input>) -> WorkerResult<Self> {
102///         Ok(self.0.saturating_add(input))
103///     }
104/// }
105///
106/// struct MyQueen;
107///
108/// impl Queen for MyQueen {
109///     type Kind = MyWorker;
110///
111///     fn create(&self) -> Self::Kind {
112///         MyWorker::default()
113///     }
114/// }
115/// ```
116#[derive(Default, Debug)]
117#[debug("DefaultQueen<{}>", any::type_name::<W>())]
118pub struct DefaultQueen<W>(PhantomData<W>);
119
120impl<W: Worker + Send + Sync + Default> Clone for DefaultQueen<W> {
121    fn clone(&self) -> Self {
122        Self::default()
123    }
124}
125
126impl<W: Worker + Send + Sync + Default> Queen for DefaultQueen<W> {
127    type Kind = W;
128
129    fn create(&self) -> Self::Kind {
130        Self::Kind::default()
131    }
132}
133
134/// A `Queen` that can create a `Worker` type that implements `Clone`, by making copies of
135/// an existing instance of that `Worker` type.
136#[derive(Debug)]
137#[debug("CloneQueen<{}>", any::type_name::<W>())]
138pub struct CloneQueen<W>(W);
139
140impl<W: Worker + Clone> CloneQueen<W> {
141    pub fn new(worker: W) -> Self {
142        CloneQueen(worker)
143    }
144}
145
146impl<W: Worker + Send + Sync + Clone> Clone for CloneQueen<W> {
147    fn clone(&self) -> Self {
148        Self(self.0.clone())
149    }
150}
151
152impl<W: Worker + Send + Sync + Default> Default for CloneQueen<W> {
153    fn default() -> Self {
154        Self(W::default())
155    }
156}
157
158impl<W: Worker + Send + Sync + Clone> Queen for CloneQueen<W> {
159    type Kind = W;
160
161    fn create(&self) -> Self::Kind {
162        self.0.clone()
163    }
164}
165
166#[cfg(test)]
167#[cfg_attr(coverage_nightly, coverage(off))]
168mod tests {
169    use super::{CloneQueen, DefaultQueen, Queen, QueenCell, QueenMut};
170    use crate::bee::stock::EchoWorker;
171
172    #[derive(Default, Debug, Clone)]
173    struct TestQueen(usize);
174
175    impl QueenMut for TestQueen {
176        type Kind = EchoWorker<u32>;
177
178        fn create(&mut self) -> Self::Kind {
179            self.0 += 1;
180            EchoWorker::default()
181        }
182    }
183
184    #[test]
185    fn test_queen_cell() {
186        let queen = QueenCell::new(TestQueen(0));
187        for _ in 0..10 {
188            let _worker = queen.create();
189        }
190        assert_eq!(queen.get().0, 10);
191        assert_eq!(queen.into_inner().0, 10);
192    }
193
194    #[test]
195    fn test_queen_cell_default() {
196        let queen = QueenCell::<TestQueen>::default();
197        for _ in 0..10 {
198            let _worker = queen.create();
199        }
200        assert_eq!(queen.get().0, 10);
201    }
202
203    #[test]
204    fn test_queen_cell_clone() {
205        let queen = QueenCell::<TestQueen>::default();
206        for _ in 0..10 {
207            let _worker = queen.create();
208        }
209        assert_eq!(queen.clone().get().0, 10);
210    }
211
212    #[test]
213    fn test_queen_cell_debug() {
214        let queen = QueenCell::<TestQueen>::default();
215        for _ in 0..10 {
216            let _worker = queen.create();
217        }
218        assert_eq!(format!("{:?}", queen), "QueenCell { queen: TestQueen(10) }");
219    }
220
221    #[test]
222    fn test_queen_cell_from() {
223        let queen = QueenCell::from(TestQueen::default());
224        for _ in 0..10 {
225            let _worker = queen.create();
226        }
227        assert_eq!(queen.get().0, 10);
228    }
229
230    #[test]
231    fn test_default_queen() {
232        let queen1 = DefaultQueen::<EchoWorker<u32>>::default();
233        let worker1 = queen1.create();
234        let queen2 = queen1.clone();
235        let worker2 = queen2.create();
236        assert_eq!(worker1, worker2);
237    }
238
239    #[test]
240    fn test_clone_queen() {
241        let worker = EchoWorker::<u32>::default();
242        let queen = CloneQueen::new(worker);
243        let worker1 = queen.create();
244        let queen2 = queen.clone();
245        let worker2 = queen2.create();
246        assert_eq!(worker1, worker2);
247    }
248
249    #[test]
250    fn test_clone_queen_default() {
251        // `CloneQueen` is `Default` when its `Worker` is `Default`
252        let queen = CloneQueen::<EchoWorker<u32>>::default();
253        let worker1 = queen.create();
254        let worker2 = queen.create();
255        assert_eq!(worker1, worker2);
256    }
257}