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
use std::future::{ready, Future};

/** The factory trait is used to populate the Pool when items are
created and replaced. There is a default implementation of factory
for boxed sync closures, and creating an asynchronous factory is
shown in this example:

```
use std::future::Future;
use lazy_pool::Factory;

struct AsyncFactory {}

struct AnyObject {
    member: String,
}

impl AsyncFactory {
    async fn get_instance(&self) -> AnyObject {
        AnyObject {
            member: String::from("hello"),
        }
    }
}

impl Factory<AnyObject> for AsyncFactory {
    fn produce(&mut self) -> Box<dyn Future<Output = AnyObject> + Send + Unpin + '_> {
        Box::new(Box::pin(self.get_instance()))
    }
}
````
*/
pub trait Factory<T>: Send
where
    T: Send,
{
    fn produce(&mut self) -> Box<dyn Future<Output = T> + Unpin + Send + '_>;
}

pub struct SyncFactory<T> {
    func: Box<dyn Fn() -> T + Send + Sync>,
}

impl<T> Factory<T> for SyncFactory<T>
where
    T: Send + 'static,
{
    fn produce(&mut self) -> Box<dyn Future<Output = T> + Unpin + Send + '_> {
        Box::new(ready((self.func)()))
    }
}

impl<C, T> From<C> for SyncFactory<T>
where
    C: Fn() -> T + Send + Sync + 'static,
{
    fn from(func: C) -> Self {
        Self {
            func: Box::new(func),
        }
    }
}