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
use std::future::Future;
use std::pin::Pin;

/// Task is used to do asynchronous operations
pub struct Task<MSG> {
    pub(crate) task: Pin<Box<dyn Future<Output = MSG>>>,
}

impl<MSG> Task<MSG>
where
    MSG: 'static,
{
    /// create a new task from a function which returns a future
    pub fn new<F>(f: F) -> Self
    where
        F: Future<Output = MSG> + 'static,
    {
        Self { task: Box::pin(f) }
    }

    /// apply a function to the msg to create a different task which has a different msg
    pub fn map_msg<F, MSG2>(self, f: F) -> Task<MSG2>
    where
        F: Fn(MSG) -> MSG2 + 'static,
        MSG2: 'static,
    {
        let task = self.task;
        Task::new(async move {
            let msg = task.await;
            f(msg)
        })
    }
}

impl<F, MSG> From<F> for Task<MSG>
where
    F: Future<Output = MSG> + 'static,
    MSG: 'static,
{
    fn from(f: F) -> Self {
        Task::new(f)
    }
}