use crate::api::problem::Problem;
fn extract_trace_id() -> Option<String> {
tracing::Span::current().id().map(|id| format!("{id:?}"))
}
pub trait WithTraceContext {
#[must_use]
fn with_trace_context(self, instance: impl Into<String>) -> Self;
}
impl WithTraceContext for Problem {
fn with_trace_context(mut self, instance: impl Into<String>) -> Self {
self = self.with_instance(instance);
if let Some(tid) = extract_trace_id() {
self = self.with_trace_id(tid);
}
self
}
}
pub trait WithRequestContext {
#[must_use]
fn with_request_context(self, uri: &axum::http::Uri) -> Self;
}
impl WithRequestContext for Problem {
fn with_request_context(self, uri: &axum::http::Uri) -> Self {
self.with_trace_context(uri.path())
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
#[test]
fn test_with_trace_context() {
use http::StatusCode;
let problem = Problem::new(StatusCode::NOT_FOUND, "Not Found", "Resource not found")
.with_trace_context("/tests/v1/users/123");
assert_eq!(problem.instance, "/tests/v1/users/123");
}
#[test]
fn test_with_request_context() {
use axum::http::Uri;
use http::StatusCode;
let uri: Uri = "/tests/v1/users/123".parse().unwrap();
let problem = Problem::new(StatusCode::NOT_FOUND, "Not Found", "Resource not found")
.with_request_context(&uri);
assert_eq!(problem.instance, "/tests/v1/users/123");
}
}