use axum::extract::FromRequestParts;
use axum::http::request::Parts;
use std::future::Future;
use std::sync::Arc;
use tracing::Span;
use crate::ports::Defer;
use crate::problem::Problem;
#[derive(Clone)]
pub struct Scope {
pub request_id: String,
pub defer: Arc<dyn Defer>,
pub span: Span,
}
impl std::fmt::Debug for Scope {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Scope")
.field("request_id", &self.request_id)
.field("span", &self.span.metadata().map(tracing::Metadata::name))
.finish_non_exhaustive()
}
}
impl<S> FromRequestParts<S> for Scope
where
S: Send + Sync,
{
type Rejection = Problem;
fn from_request_parts(
parts: &mut Parts,
_state: &S,
) -> impl Future<Output = Result<Self, Self::Rejection>> + Send {
std::future::ready(
parts
.extensions
.get::<Scope>()
.cloned()
.ok_or_else(Problem::internal),
)
}
}