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
//! Module `query` contains types and helpful abstractions to model Domain Queries
//! and implement Domain Query Handlers.

use async_trait::async_trait;
use futures::Future;

use crate::message;

/// A [Message][message::Message] carrying the Domain Query itself as payload
/// and other relevant information as metadata.
pub type Envelope<T> = message::Envelope<T>;

/// An Handler describes an implementation that is able to handle specific [Queries][Envelope].
///
/// The Handler evaluates the Domain Query and produces a **result**, here described
/// through the [Output][Handler::Output] associated type.
#[async_trait]
pub trait Handler<T>: Send + Sync
where
    T: message::Message + Send + Sync,
{
    /// The result type the Handler produces when evaluating a Query.
    type Output: Send + Sync;
    /// The error type returned by the Handler when Query evaluation fails.
    type Error: Send + Sync;

    /// Evaluates the [Query][Envelope] provided and returns a result type,
    /// described by the [Output][Handler::Output] parameter.
    ///
    /// # Errors
    ///
    /// As the Handler can fail to evaluate the Query, an [Error][Handler::Error]
    /// can be returned instead.
    async fn handle(&self, query: Envelope<T>) -> Result<Self::Output, Self::Error>;
}

#[async_trait]
impl<T, R, Err, F, Fut> Handler<T> for F
where
    T: message::Message + Send + Sync + 'static,
    R: Send + Sync,
    Err: Send + Sync,
    F: Send + Sync + Fn(Envelope<T>) -> Fut,
    Fut: Send + Sync + Future<Output = Result<R, Err>>,
{
    type Output = R;
    type Error = Err;

    async fn handle(&self, command: Envelope<T>) -> Result<R, Self::Error> {
        self(command).await
    }
}