nitinol_resolver/
resolver.rs1use std::fmt::{Debug, Display};
2use std::marker::PhantomData;
3
4use async_trait::async_trait;
5use nitinol_core::event::Event;
6
7use crate::errors::ResolveError;
8
9#[derive(Debug, Clone, Hash, Eq, PartialEq)]
10pub struct ResolveType {
11 event: &'static str,
12 handler: &'static str,
13}
14
15impl ResolveType {
16 pub const fn new(event: &'static str, handler: &'static str) -> Self {
17 Self { event, handler }
18 }
19
20 pub fn event(&self) -> &'static str {
21 self.event
22 }
23
24 pub fn handler(&self) -> &'static str {
25 self.handler
26 }
27}
28
29impl Display for ResolveType {
30 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
31 write!(f, "{}-{}", self.event, self.handler)
32 }
33}
34
35#[async_trait]
36pub trait ResolveHandler<E: Event, T>: 'static + Sync + Send {
37 const HANDLER_TYPE: &'static str;
38 type Error: Debug + Sync + Send + 'static;
39 async fn apply(entity: &mut Option<T>, event: E) -> Result<(), Self::Error>;
40}
41
42pub trait ResolverType<T>
43where
44 Self: Resolver<T>
45{
46 const RESOLVE_TYPE: &'static str;
47}
48
49#[async_trait]
50pub trait Resolver<T>: 'static + Sync + Send {
51 async fn resolve(&self, entity: &mut Option<T>, payload: &[u8]) -> Result<(), ResolveError>;
52}
53
54pub(crate) struct TypedResolver<E: Event, T, H> {
55 _event: PhantomData<E>,
56 _resolve: PhantomData<T>,
57 _handler: PhantomData<H>,
58}
59
60impl<E: Event, T, H: ResolveHandler<E, T>> Default for TypedResolver<E, T, H> {
61 fn default() -> Self {
62 Self {
63 _event: Default::default(),
64 _resolve: Default::default(),
65 _handler: Default::default(),
66 }
67 }
68}
69
70#[async_trait]
71impl<E: Event, T, H> Resolver<T> for TypedResolver<E, T, H>
72where
73 T: 'static + Sync + Send,
74 H: ResolveHandler<E, T>,
75{
76 async fn resolve(&self, entity: &mut Option<T>, payload: &[u8]) -> Result<(), ResolveError> {
77 let event = E::from_bytes(payload)?;
78 if let Err(reason) = H::apply(entity, event).await {
79 tracing::error!("{:?}", reason);
80 return Err(ResolveError::InProcess {
81 trace: format!("{:?}", reason),
82 });
83 }
84 Ok(())
85 }
86}