use crate::{Push, XSpanIdString};
use futures::FutureExt;
use http::Request;
use std::marker::PhantomData;
#[derive(Debug)]
pub struct AddContextMakeService<T, C>
where
C: Default + Push<XSpanIdString> + 'static + Send,
C::Result: Send + 'static,
{
inner: T,
marker: PhantomData<C>,
}
impl<T, C> AddContextMakeService<T, C>
where
C: Default + Push<XSpanIdString> + 'static + Send,
C::Result: Send + 'static,
{
pub fn new(inner: T) -> Self {
AddContextMakeService {
inner,
marker: PhantomData,
}
}
}
impl<Inner, Context, Target> hyper::service::Service<Target>
for AddContextMakeService<Inner, Context>
where
Context: Default + Push<XSpanIdString> + 'static + Send,
Context::Result: Send + 'static,
Inner: hyper::service::Service<Target>,
Inner::Future: Send + 'static,
{
type Error = Inner::Error;
type Response = AddContextService<Inner::Response, Context>;
type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
fn call(&self, target: Target) -> Self::Future {
Box::pin(
self.inner
.call(target)
.map(|s| Ok(AddContextService::new(s?))),
)
}
}
#[derive(Debug)]
pub struct AddContextService<T, C>
where
C: Default + Push<XSpanIdString>,
C::Result: Send + 'static,
{
inner: T,
marker: PhantomData<C>,
}
impl<T, C> AddContextService<T, C>
where
C: Default + Push<XSpanIdString>,
C::Result: Send + 'static,
{
pub fn new(inner: T) -> Self {
AddContextService {
inner,
marker: PhantomData,
}
}
}
impl<Inner, Context, Body> hyper::service::Service<Request<Body>>
for AddContextService<Inner, Context>
where
Context: Default + Push<XSpanIdString> + Send + 'static,
Context::Result: Send + 'static,
Inner: hyper::service::Service<(Request<Body>, Context::Result)>,
{
type Response = Inner::Response;
type Error = Inner::Error;
type Future = Inner::Future;
fn call(&self, req: Request<Body>) -> Self::Future {
let x_span_id = XSpanIdString::get_or_generate(&req);
let context = Context::default().push(x_span_id);
self.inner.call((req, context))
}
}