use rama::{Context, Layer, Service};
use tansu_sans_io::{ApiKey, Body, Frame};
use crate::coordinator::group::Coordinator;
pub mod group;
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CoordinatorService<C, S> {
coordinator: C,
inner: S,
}
impl<C, S> ApiKey for CoordinatorService<C, S>
where
S: ApiKey,
{
const KEY: i16 = S::KEY;
}
impl<C, S, State> Service<State, Frame> for CoordinatorService<C, S>
where
S: Service<C, Frame>,
S::Response: Into<Body>,
C: Coordinator,
State: Send + Sync + 'static,
{
type Response = Body;
type Error = S::Error;
async fn serve(&self, ctx: Context<State>, req: Frame) -> Result<Self::Response, Self::Error> {
let (ctx, _) = ctx.swap_state(self.coordinator.clone());
self.inner.serve(ctx, req).await.map(Into::into)
}
}
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct CoordinatorLayer<C> {
coordinator: C,
}
impl<C> CoordinatorLayer<C> {
pub fn new(coordinator: C) -> Self {
Self { coordinator }
}
}
impl<C, S> Layer<S> for CoordinatorLayer<C>
where
C: Coordinator,
{
type Service = CoordinatorService<C, S>;
fn layer(&self, inner: S) -> Self::Service {
Self::Service {
coordinator: self.coordinator.clone(),
inner,
}
}
}