roopes_core/aggregates/subscribing_handler/
mod.rs

1//!
2#![cfg_attr(feature = "doc-images",
3  cfg_attr(
4    all(),
5    doc = ::embed_doc_image::embed_image!(
6        "subscribing-handler-diagram",
7        "src/aggregates/subscribing_handler/subscribing_handler.svg"
8)))]
9#![cfg_attr(
10    not(feature = "doc-images"),
11    doc = "**Doc images not enabled**. Compile with feature `doc-images` and \
12           Rust version >= 1.54 to enable."
13)]
14//! The [`subscribing_handler`] module creates
15//! [`Subscriber`]s from arbitrary [`Handler`]s.
16//!
17//! ![subscribing handler diagram][subscribing-handler-diagram]
18
19use crate::prelude::{
20    handler::lambda::Delegate,
21    publisher_subscriber::heap,
22    *,
23};
24use delegate::delegate;
25use std::{
26    hash::Hash,
27    marker::PhantomData,
28};
29
30#[cfg(test)]
31mod tests;
32
33/// Exposes the [`SubscribingHandler`] type at the
34/// library level.
35pub mod prelude
36{
37    pub use super::SubscribingHandler;
38}
39
40/// Provides the [`Subscriber`] and [`Handler`]
41/// traits for a wrapped [`Handler`] delegate.
42pub struct SubscribingHandler<H, M>
43where
44    H: Handler<M>,
45{
46    handler: H,
47    _retain_types: PhantomData<M>,
48}
49
50impl<H, M> SubscribingHandler<H, M>
51where
52    H: Handler<M>,
53{
54    /// Creates a [`SubscribingHandler`] from a
55    /// given [`Handler`].
56    pub fn new(handler: H) -> SubscribingHandler<H, M>
57    {
58        SubscribingHandler {
59            handler,
60            _retain_types: PhantomData,
61        }
62    }
63}
64
65impl<H, M> SubscribingHandler<H, M>
66where
67    H: Handler<M> + 'static,
68    M: 'static,
69{
70    /// Wraps the [`SubscribingHandler`] in a [`Box`] and [`heap::Subscriber`].
71    pub fn into_heap(self) -> heap::Subscriber<M>
72    {
73        heap::Subscriber::new(Box::new(self))
74    }
75}
76
77impl<H, M> Subscriber<M> for SubscribingHandler<H, M>
78where
79    H: Handler<M>,
80{
81    fn receive(
82        &self,
83        message: &M,
84    )
85    {
86        self.handler.handle(message);
87    }
88}
89
90#[allow(clippy::inline_always)]
91impl<H, M> Handler<M> for SubscribingHandler<H, M>
92where
93    H: Handler<M>,
94{
95    delegate! {
96        to self.handler{
97            fn handle(
98                &self,
99                message: &M,
100            );
101        }
102    }
103}
104
105impl<H, M> From<H> for SubscribingHandler<H, M>
106where
107    H: Handler<M>,
108{
109    fn from(handler: H) -> Self
110    {
111        SubscribingHandler::new(handler)
112    }
113}
114
115impl<H, M> PartialEq for SubscribingHandler<H, M>
116where
117    H: PartialEq + Handler<M>,
118{
119    fn eq(
120        &self,
121        other: &Self,
122    ) -> bool
123    {
124        self.handler.eq(&other.handler)
125    }
126}
127
128impl<H, M> Eq for SubscribingHandler<H, M> where H: Eq + Handler<M> {}
129
130impl<H, M> Hash for SubscribingHandler<H, M>
131where
132    H: Handler<M> + Hash,
133{
134    fn hash<S: std::hash::Hasher>(
135        &self,
136        state: &mut S,
137    )
138    {
139        self.handler.hash(state);
140    }
141}
142
143/// Provides the ability to convert a [`Handler`] into a
144/// [`SubscribingHandler`], for use as a [`Subscriber`].
145pub trait IntoSubscriber<H, M>
146where
147    H: Handler<M>,
148{
149    /// Wraps the [`Handler`] in a [`SubscribingHandler`], for use as a
150    /// [`Subscriber`].
151    fn into_subscriber(self) -> SubscribingHandler<H, M>;
152}
153
154impl<H, M> IntoSubscriber<H, M> for H
155where
156    H: Handler<M>,
157{
158    fn into_subscriber(self) -> SubscribingHandler<H, M>
159    {
160        SubscribingHandler::new(self)
161    }
162}