nitinol_resolver/
resolver.rs

1use 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}