use super::pipeline::{MessageContext, MessageProcessor};
use crate::common::error::Result;
use crate::common::protocol::Frame;
use async_trait::async_trait;
use std::sync::Arc;
pub struct FunctionProcessor {
name: String,
#[allow(clippy::type_complexity)]
handler: Arc<
dyn Fn(
&MessageContext,
)
-> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<Frame>>> + Send>>
+ Send
+ Sync,
>,
}
impl FunctionProcessor {
pub fn new<F, Fut>(name: impl Into<String>, handler: F) -> Self
where
F: Fn(&MessageContext) -> Fut + Send + Sync + 'static,
Fut: std::future::Future<Output = Result<Option<Frame>>> + Send + 'static,
{
Self {
name: name.into(),
handler: Arc::new(move |ctx| Box::pin(handler(ctx))),
}
}
}
#[async_trait]
impl MessageProcessor for FunctionProcessor {
async fn process(&self, ctx: &MessageContext) -> Result<Option<Frame>> {
(self.handler)(ctx).await
}
fn name(&self) -> &str {
&self.name
}
}
pub struct DelegateProcessor {
name: String,
#[allow(clippy::type_complexity)]
handler: Arc<
dyn Fn(
&Frame,
Option<&str>,
)
-> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Option<Frame>>> + Send>>
+ Send
+ Sync,
>,
}
impl DelegateProcessor {
pub fn new<F, Fut>(name: impl Into<String>, handler: F) -> Self
where
F: Fn(&Frame, Option<&str>) -> Fut + Send + Sync + 'static,
Fut: std::future::Future<Output = Result<Option<Frame>>> + Send + 'static,
{
Self {
name: name.into(),
handler: Arc::new(move |frame, conn_id| Box::pin(handler(frame, conn_id))),
}
}
}
#[async_trait]
impl MessageProcessor for DelegateProcessor {
async fn process(&self, ctx: &MessageContext) -> Result<Option<Frame>> {
(self.handler)(&ctx.frame, ctx.connection_id.as_deref()).await
}
fn name(&self) -> &str {
&self.name
}
}