1use std::sync::Arc;
11
12use tokio::sync::mpsc;
13use tokio_util::sync::CancellationToken;
14
15use rskit_errors::AppResult;
16use rskit_provider::traits::{Provider, RequestResponse};
17
18use crate::event::Event;
19use crate::handler::Handler;
20
21struct ProviderHandler<I, O, P> {
26 provider: Arc<P>,
27 _ph: std::marker::PhantomData<fn(I) -> O>,
28}
29
30#[async_trait::async_trait]
31impl<I, O, P> Handler<I, O> for ProviderHandler<I, O, P>
32where
33 I: Send + 'static,
34 O: Send + Clone + 'static,
35 P: RequestResponse<I, O> + Send + Sync + 'static,
36{
37 async fn handle(
38 &self,
39 task: I,
40 _emit: mpsc::Sender<Event<O>>,
41 _cancel: CancellationToken,
42 ) -> AppResult<O> {
43 self.provider.execute(task).await
44 }
45}
46
47pub fn from_provider<I, O, P>(provider: Arc<P>) -> impl Handler<I, O>
51where
52 I: Send + 'static,
53 O: Send + Clone + 'static,
54 P: RequestResponse<I, O> + Send + Sync + 'static,
55{
56 ProviderHandler {
57 provider,
58 _ph: std::marker::PhantomData,
59 }
60}
61
62struct HandlerProvider<I, O> {
67 name: &'static str,
68 handler: Arc<dyn Handler<I, O>>,
69}
70
71#[async_trait::async_trait]
72impl<I, O> Provider for HandlerProvider<I, O>
73where
74 I: Send + 'static,
75 O: Send + Clone + 'static,
76{
77 fn name(&self) -> &'static str {
78 self.name
79 }
80}
81
82#[async_trait::async_trait]
83impl<I, O> RequestResponse<I, O> for HandlerProvider<I, O>
84where
85 I: Send + 'static,
86 O: Send + Clone + 'static,
87{
88 async fn execute(&self, input: I) -> AppResult<O> {
89 let (emit_tx, mut emit_rx) = mpsc::channel::<Event<O>>(64);
90 let cancel = CancellationToken::new();
91
92 tokio::spawn(async move { while emit_rx.recv().await.is_some() {} });
95
96 self.handler.handle(input, emit_tx, cancel).await
97 }
98}
99
100pub fn as_provider<I, O>(
102 name: &'static str,
103 handler: Arc<dyn Handler<I, O>>,
104) -> impl RequestResponse<I, O>
105where
106 I: Send + 'static,
107 O: Send + Clone + 'static,
108{
109 HandlerProvider { name, handler }
110}