nitinol_resolver/mapping.rs
1#[cfg(feature = "process")]
2pub mod process;
3
4use std::collections::HashMap;
5use std::sync::Arc;
6
7use nitinol_core::event::Event;
8
9use crate::resolver::{ResolveHandler, ResolveType, Resolver, ResolverType, TypedResolver};
10
11/// ResolveMapping is a trait that defines the mapping of event types to their respective handlers.
12///
13/// ## Example
14/// ```rust
15/// # use async_trait::async_trait;
16/// # use serde::{Deserialize, Serialize};
17/// # use nitinol_core::errors::{DeserializeError, SerializeError};
18/// # use nitinol_core::event::Event;
19/// # use nitinol_resolver::resolver::ResolveHandler;
20/// #
21/// # pub struct Entity;
22/// #
23/// # #[derive(Debug, Deserialize, Serialize)]
24/// # pub enum EntityEvent {}
25/// #
26/// # impl Event for EntityEvent {
27/// # const EVENT_TYPE: &'static str = "entity-event";
28/// #
29/// # fn as_bytes(&self) -> Result<Vec<u8>, SerializeError> {
30/// # Ok(serde_json::to_vec(self)?)
31/// # }
32/// # fn from_bytes(bytes: &[u8]) -> Result<Self, DeserializeError> {
33/// # Ok(serde_json::from_slice(bytes)?)
34/// # }
35/// # }
36/// #
37/// # pub struct Subscribe;
38/// #
39/// # #[async_trait]
40/// # pub trait SubscribeHandler<E: Event>: 'static + Sync + Send + Sized {
41/// # type Rejection: std::fmt::Debug + Sync + Send + 'static;
42/// # async fn on(&mut self, event: E) -> Result<(), Self::Rejection>;
43/// # }
44/// #
45/// # #[async_trait]
46/// # impl<E: Event, T> ResolveHandler<E, T> for Subscribe
47/// # where
48/// # T: SubscribeHandler<E>,
49/// # {
50/// # const HANDLER_TYPE: &'static str = "subscribe";
51/// # type Error = T::Rejection;
52/// #
53/// # async fn apply(entity: &mut Option<T>, event: E) -> Result<(), Self::Error> {
54/// # let Some(entity) = entity else {
55/// # panic!("Entity must exist in this process.");
56/// # };
57/// #
58/// # entity.on(event).await?;
59/// #
60/// # Ok(())
61/// # }
62/// # }
63/// #
64/// use nitinol_resolver::mapping::{Mapper, ResolveMapping};
65///
66/// #[async_trait]
67/// impl SubscribeHandler<EntityEvent> for Entity {
68/// type Rejection = String;
69/// async fn on(&mut self, event: EntityEvent) -> Result<(), Self::Rejection> {
70/// // something process...
71/// Ok(())
72/// }
73/// }
74///
75/// impl ResolveMapping for Entity {
76/// fn mapping(mapper: &mut Mapper<Self>) {
77/// // Register the event type and its handler
78/// // This `Subscribe` shown as an example points out a compile error,
79/// // if the above `SubscribeHandler` is not implemented for the Entity type.
80/// mapper.register::<EntityEvent, Subscribe>();
81/// }
82/// }
83/// ```
84pub trait ResolveMapping: 'static + Sync + Send + Sized {
85 fn mapping(mapper: &mut Mapper<Self>);
86}
87
88pub struct Mapper<T> {
89 map: HashMap<ResolveType, Arc<dyn Resolver<T>>>,
90}
91
92impl<T> Mapper<T>
93where
94 T: 'static + Sync + Send,
95{
96 pub fn register<E: Event, H>(&mut self) -> &mut Self
97 where
98 H: ResolveHandler<E, T>,
99 {
100 self.map.insert(
101 ResolveType::new(E::EVENT_TYPE, H::HANDLER_TYPE),
102 Arc::new(TypedResolver::<E, T, H>::default()),
103 );
104 self
105 }
106
107 pub fn register_with<E: Event, R>(&mut self, resolver: R) -> &mut Self
108 where
109 R: ResolverType<T>
110 {
111 self.map.insert(
112 ResolveType::new(E::EVENT_TYPE, R::RESOLVE_TYPE),
113 Arc::new(resolver),
114 );
115 self
116 }
117
118 pub fn find(&self, mut f: impl FnMut(&ResolveType) -> bool) -> Option<Arc<dyn Resolver<T>>> {
119 self.map
120 .iter()
121 .find(|(key, _)| f(key))
122 .map(|(_, handler)| handler)
123 .cloned()
124 }
125
126 pub fn filter(self, mut f: impl FnMut(&ResolveType) -> bool) -> Self {
127 Self {
128 map: self.map.into_iter()
129 .filter(|(key, _)| f(key))
130 .collect(),
131 }
132 }
133}
134
135impl<T> Default for Mapper<T> {
136 fn default() -> Self {
137 Self {
138 map: HashMap::default(),
139 }
140 }
141}