use crate::routes::HandlerArgs;
use core::fmt;
use pin_project::pin_project;
use serde_json::value::RawValue;
use std::{
convert::Infallible,
future::Future,
task::{Context, Poll},
};
use tower::util::{BoxCloneSyncService, Oneshot};
#[pin_project]
pub struct RouteFuture {
#[pin]
inner: Oneshot<BoxCloneSyncService<HandlerArgs, Box<RawValue>, Infallible>, HandlerArgs>,
span: Option<tracing::Span>,
}
impl RouteFuture {
pub const fn new(
inner: Oneshot<BoxCloneSyncService<HandlerArgs, Box<RawValue>, Infallible>, HandlerArgs>,
) -> Self {
Self { inner, span: None }
}
pub const fn new_with_span(
inner: Oneshot<BoxCloneSyncService<HandlerArgs, Box<RawValue>, Infallible>, HandlerArgs>,
span: tracing::Span,
) -> Self {
Self {
inner,
span: Some(span),
}
}
pub fn with_span(self, span: tracing::Span) -> Self {
Self {
span: Some(span),
..self
}
}
}
impl fmt::Debug for RouteFuture {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RouteFuture").finish_non_exhaustive()
}
}
impl Future for RouteFuture {
type Output = Result<Box<RawValue>, Infallible>;
fn poll(self: std::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let this = self.project();
let _enter = this.span.as_ref().map(tracing::Span::enter);
this.inner.poll(cx)
}
}