use std::sync::Arc;
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;
use rskit_errors::AppResult;
use rskit_provider::traits::{Provider, RequestResponse};
use crate::event::Event;
use crate::handler::Handler;
struct ProviderHandler<I, O, P> {
provider: Arc<P>,
_ph: std::marker::PhantomData<fn(I) -> O>,
}
#[async_trait::async_trait]
impl<I, O, P> Handler<I, O> for ProviderHandler<I, O, P>
where
I: Send + 'static,
O: Send + Clone + 'static,
P: RequestResponse<I, O> + Send + Sync + 'static,
{
async fn handle(
&self,
task: I,
_emit: mpsc::Sender<Event<O>>,
_cancel: CancellationToken,
) -> AppResult<O> {
self.provider.execute(task).await
}
}
pub fn from_provider<I, O, P>(provider: Arc<P>) -> impl Handler<I, O>
where
I: Send + 'static,
O: Send + Clone + 'static,
P: RequestResponse<I, O> + Send + Sync + 'static,
{
ProviderHandler {
provider,
_ph: std::marker::PhantomData,
}
}
struct HandlerProvider<I, O> {
name: &'static str,
handler: Arc<dyn Handler<I, O>>,
}
#[async_trait::async_trait]
impl<I, O> Provider for HandlerProvider<I, O>
where
I: Send + 'static,
O: Send + Clone + 'static,
{
fn name(&self) -> &'static str {
self.name
}
}
#[async_trait::async_trait]
impl<I, O> RequestResponse<I, O> for HandlerProvider<I, O>
where
I: Send + 'static,
O: Send + Clone + 'static,
{
async fn execute(&self, input: I) -> AppResult<O> {
let (emit_tx, mut emit_rx) = mpsc::channel::<Event<O>>(64);
let cancel = CancellationToken::new();
tokio::spawn(async move { while emit_rx.recv().await.is_some() {} });
self.handler.handle(input, emit_tx, cancel).await
}
}
pub fn as_provider<I, O>(
name: &'static str,
handler: Arc<dyn Handler<I, O>>,
) -> impl RequestResponse<I, O>
where
I: Send + 'static,
O: Send + Clone + 'static,
{
HandlerProvider { name, handler }
}