botx_api_framework/handlers/
internal_bot_notification.rs1use std::{any::{Any, TypeId}, marker::PhantomData, ops::Deref};
2
3use anthill_di::{*, types::BuildDependencyResult};
4use serde::Deserialize;
5
6use crate::{contexts::RequestContext, results::CommandResult};
7
8pub struct InternalBotNotificationHandlerTypeId(pub TypeId);
9
10impl Deref for InternalBotNotificationHandlerTypeId {
11 type Target = TypeId;
12
13 fn deref(&self) -> &Self::Target { &self.0 }
14}
15
16#[async_trait_with_sync::async_trait]
17pub trait IInternalBotNotificationHandler: Send + Sync {
18 type TData: Sync + Send + for<'de> Deserialize<'de> + 'static;
19 type TOptions: Sync + Send + for<'de> Deserialize<'de> + 'static;
20
21 async fn handle(&mut self, data: Self::TData, options: Self::TOptions, request_context: RequestContext) -> CommandResult;
22}
23
24pub trait IInternalBotNotificationDataProcessor: Sync + Send {
25 fn get_data(&self, data: &serde_json::Value) -> Option<Box<dyn Any + Sync + Send>>;
26 fn get_options(&self, options: &serde_json::Value) -> Option<Box<dyn Any + Sync + Send>>;
27 fn get_handler_type_id(&self) -> InternalBotNotificationHandlerTypeId;
28}
29
30pub struct InternalBotNotificationDataProcessor<THandler: IInternalBotNotificationHandler + 'static> {
32 handler_pd: PhantomData<THandler>
33}
34
35impl<THandler: IInternalBotNotificationHandler + 'static> IInternalBotNotificationDataProcessor for InternalBotNotificationDataProcessor<THandler> {
36 fn get_data(&self, data: &serde_json::Value) -> Option<Box<dyn Any + Sync + Send>> {
37 serde_json::value::from_value::<THandler::TData>(data.clone())
38 .map(|x| Box::new(x) as Box<dyn Any + Sync + Send>)
39 .ok()
40 }
41
42 fn get_options(&self, options: &serde_json::Value) -> Option<Box<dyn Any + Sync + Send>> {
43 serde_json::value::from_value::<THandler::TOptions>(options.clone())
44 .map(|x| Box::new(x) as Box<dyn Any + Sync + Send>)
45 .ok()
46 }
47
48 fn get_handler_type_id(&self) -> InternalBotNotificationHandlerTypeId {
49 InternalBotNotificationHandlerTypeId(TypeId::of::<THandler>())
50 }
51}
52
53#[async_trait_with_sync::async_trait(Sync)]
54impl<THandler: IInternalBotNotificationHandler + 'static> Constructor for InternalBotNotificationDataProcessor<THandler> {
55 async fn ctor(_: DependencyContext) -> BuildDependencyResult<Self> {
56 Ok(Self { handler_pd: Default::default() })
57 }
58}
59
60#[async_trait_with_sync::async_trait]
62pub trait IInternalBotNotificationCallProducer: Send + Sync {
63 async fn handle(&mut self, data: Box<dyn Any + Sync + Send>, options: Box<dyn Any + Sync + Send>, request_context: RequestContext) -> CommandResult;
64}
65
66#[async_trait_with_sync::async_trait]
67impl<T: IInternalBotNotificationHandler + 'static> IInternalBotNotificationCallProducer for T
68{
69 async fn handle(&mut self, data: Box<dyn Any + Sync + Send>, options: Box<dyn Any + Sync + Send>, request_context: RequestContext) -> CommandResult {
70 let data = unsafe {
71 *data.downcast_unchecked::<T::TData>()
72 };
73
74 let options = unsafe {
75 *options.downcast_unchecked::<T::TOptions>()
76 };
77
78 T::handle(self, data, options, request_context).await
79 }
80}