mm1_sup/common/
factory.rs

1use std::marker::PhantomData;
2use std::sync::Arc;
3
4use parking_lot::Mutex;
5
6pub trait ActorFactory: Send + Sync + 'static {
7    type Args: Send + 'static;
8    type Runnable;
9    fn produce(&self, args: Self::Args) -> Self::Runnable;
10}
11
12#[derive(Debug)]
13pub struct ActorFactoryMut<F, A, R>(Arc<Mutex<F>>, PhantomData<(A, R)>);
14
15#[derive(Debug)]
16pub struct ActorFactoryOnce<F, A, R>(Arc<Mutex<Option<F>>>, PhantomData<(A, R)>);
17
18impl<F, A, R> ActorFactoryMut<F, A, R>
19where
20    F: FnMut(A) -> R,
21    F: Send + 'static,
22    A: Send + 'static,
23    R: Send + 'static,
24{
25    pub fn new(f: F) -> Self {
26        Self(Arc::new(Mutex::new(f)), Default::default())
27    }
28}
29
30impl<F, A, R> ActorFactoryOnce<F, A, R>
31where
32    F: FnOnce(A) -> R,
33    F: Send + 'static,
34    A: Send + 'static,
35    R: Send + 'static,
36{
37    pub fn new(f: F) -> Self {
38        Self(Arc::new(Mutex::new(Some(f))), Default::default())
39    }
40}
41
42impl<F, A, R> Clone for ActorFactoryMut<F, A, R> {
43    fn clone(&self) -> Self {
44        Self(self.0.clone(), Default::default())
45    }
46}
47
48impl<F, A, R> Clone for ActorFactoryOnce<F, A, R> {
49    fn clone(&self) -> Self {
50        Self(self.0.clone(), Default::default())
51    }
52}
53
54impl<F, A, R> ActorFactory for ActorFactoryMut<F, A, R>
55where
56    Self: Sync + Send + 'static,
57    F: FnMut(A) -> R,
58    F: Send + 'static,
59    A: Send + 'static,
60    R: Send + 'static,
61{
62    type Args = A;
63    type Runnable = R;
64
65    fn produce(&self, args: Self::Args) -> Self::Runnable {
66        (self.0.lock())(args)
67    }
68}
69
70impl<F, A, R> ActorFactory for ActorFactoryOnce<F, A, R>
71where
72    Self: Sync + Send + 'static,
73    F: FnOnce(A) -> R,
74    F: Send + 'static,
75    // A: Message,
76    A: Send + 'static,
77    R: Send + 'static,
78{
79    type Args = A;
80    type Runnable = R;
81
82    fn produce(&self, args: Self::Args) -> Self::Runnable {
83        (self
84            .0
85            .lock()
86            .take()
87            .expect("this is a single-use actor-factory"))(args)
88    }
89}