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
use async_std::sync::Mutex;

use crate::mediator::{
    asynchronous::basic::basic::BasicAsyncMediator,
    builder::{BuilderFlow, BuilderInternal},
    listener::Listener,
    synchronous::basic::{basic::BasicMediator, interface::BasicMediatorBuilderInterface},
};
use std::{fmt::Debug, sync::mpsc::channel};

/// The [`BasicAsyncBuilder`] helps you to create a [`BasicAsyncMediator`].
///
/// The [`BasicAsyncBuilder`] is part of the builder pattern.
/// It has only two functionalities. The first one is adding a [`Listener`] via
/// [`BasicAsyncBuilder::add_listener()`].
/// The second one is the mandatory [`BuilderFlow::build()`], which returns
/// a [`BasicAsyncMediator`].
///
pub struct BasicAsyncBuilder<Ev>
where
    Ev: Debug,
{
    mediator: BasicMediator<Ev>,
}

impl<Ev> BuilderInternal<BasicAsyncMediator<Ev>, BasicAsyncBuilder<Ev>> for BasicAsyncMediator<Ev>
where
    Ev: Debug,
{
    /// Creates a [`BasicAsyncBuilder`] with the goal of producing a [`BasicAsyncMediator`].
    ///
    fn builder() -> BasicAsyncBuilder<Ev> {
        BasicAsyncBuilder::<Ev> {
            mediator: BasicMediator::<Ev> {
                channel: channel(),
                listener: vec![],
            },
        }
    }
}

impl<M, Ev> BasicMediatorBuilderInterface<M, Ev> for BasicAsyncBuilder<Ev>
where
    Ev: Debug,
{
    /// Adds a user-defined listener to the [`BasicAsyncBuilder`].
    ///
    /// To be able to supply a closure that implements [`Listener`],
    /// it must satisfy [`Send`] and `'static` bounds.
    ///
    /// Also it must be a `Fn(Ev)` with a return type of `()`
    /// where `Ev` is the user-defined event type
    /// that must be [`Clone`] and [`Debug`].
    ///
    fn add_listener<F>(mut self, f: F) -> Self
    where
        F: Listener<Ev>,
    {
        self.mediator.listener.push(Box::new(f));
        self
    }
}

impl<Ev> BasicAsyncBuilder<Ev>
where
    Ev: Debug,
{
    /// Adds a user-defined listener to the [`BasicAsyncBuilder`].
    ///
    /// The supplied type must be a [`Listener`].
    /// As such, it must implement [`Send`] and `Fn(Ev)`,
    /// besides being `'static`.
    ///
    /// As a side note, here, `Ev` is the user-defined event type
    /// that must be [`Clone`] and [`Debug`].
    ///
    /// # Examples
    ///
    /// Basic usage:
    ///
    /// ```
    /// use mediator_sys::asynchronous::basic::*;
    ///
    /// #[derive(Debug, Clone)]
    /// enum MyEvent {
    ///     One,
    ///     Two
    /// }
    ///
    /// let mediator = BasicAsyncMediator::<MyEvent>::builder()
    ///     .add_listener(|ev| {
    ///         /* Your listening logic */
    ///     })
    ///     .build();
    ///
    pub fn add_listener<F>(self, f: F) -> Self
    where
        F: Listener<Ev>,
    {
        <Self as BasicMediatorBuilderInterface<BasicMediator<Ev>, Ev>>::add_listener(self, f)
    }
}

impl<Ev> BuilderFlow<BasicAsyncMediator<Ev>> for BasicAsyncBuilder<Ev>
where
    Ev: Debug,
{
    /// Builds the [`BasicAsyncMediator`] and returns it.
    ///
    /// Because [`BasicAsyncMediator`] implements [`BuilderInternal`],
    /// which in turn means, that the [`BasicAsyncBuilder`] implements [`BuilderFlow`]
    /// and not [`crate::builder::TryBuilderFlow`], this method will
    /// always return a [`BasicAsyncMediator`] as stated by the return type.
    ///
    fn build(self) -> BasicAsyncMediator<Ev> {
        BasicAsyncMediator {
            basic: Mutex::new(self.mediator),
        }
    }
}