eventually/
query.rs

1//! Module `query` contains types and helpful abstractions to model Domain Queries
2//! and implement Domain Query Handlers.
3
4use async_trait::async_trait;
5use futures::Future;
6
7use crate::message;
8
9/// A [Message][message::Message] carrying the Domain Query itself as payload
10/// and other relevant information as metadata.
11pub type Envelope<T> = message::Envelope<T>;
12
13/// An Handler describes an implementation that is able to handle specific [Queries][Envelope].
14///
15/// The Handler evaluates the Domain Query and produces a **result**, here described
16/// through the [Output][Handler::Output] associated type.
17#[async_trait]
18pub trait Handler<T>: Send + Sync
19where
20    T: message::Message + Send + Sync,
21{
22    /// The result type the Handler produces when evaluating a Query.
23    type Output: Send + Sync;
24    /// The error type returned by the Handler when Query evaluation fails.
25    type Error: Send + Sync;
26
27    /// Evaluates the [Query][Envelope] provided and returns a result type,
28    /// described by the [Output][Handler::Output] parameter.
29    ///
30    /// # Errors
31    ///
32    /// As the Handler can fail to evaluate the Query, an [Error][Handler::Error]
33    /// can be returned instead.
34    async fn handle(&self, query: Envelope<T>) -> Result<Self::Output, Self::Error>;
35}
36
37#[async_trait]
38impl<T, R, Err, F, Fut> Handler<T> for F
39where
40    T: message::Message + Send + Sync + 'static,
41    R: Send + Sync,
42    Err: Send + Sync,
43    F: Send + Sync + Fn(Envelope<T>) -> Fut,
44    Fut: Send + Sync + Future<Output = Result<R, Err>>,
45{
46    type Output = R;
47    type Error = Err;
48
49    async fn handle(&self, command: Envelope<T>) -> Result<R, Self::Error> {
50        self(command).await
51    }
52}