hfendpoints-http/src/headers.rs (42 lines of code) (raw):

use axum::http::{HeaderName, HeaderValue}; use axum_extra::headers::{Error, Header}; use std::borrow::Cow; use std::ops::Deref; use tracing::error; pub(crate) static X_REQUEST_ID_NAME: HeaderName = HeaderName::from_static("x-request-id"); /// Holds the value of the x-request-id header used to /// correlate request and execution within the server. #[derive(Debug, Clone)] pub struct RequestId(Cow<'static, str>); impl Deref for RequestId { type Target = str; fn deref(&self) -> &Self::Target { match &self.0 { Cow::Borrowed(value) => value, Cow::Owned(value) => value.as_str(), } } } impl Header for RequestId { fn name() -> &'static HeaderName { &X_REQUEST_ID_NAME } fn decode<'i, I>(values: &mut I) -> Result<Self, Error> where Self: Sized, I: Iterator<Item = &'i HeaderValue>, { let value = values.next().ok_or_else(Error::invalid)?; Ok(RequestId(Cow::from( value .to_str() .map_err(|err| { error!("Failed to decode x-request-id header: {err}"); Error::invalid() })? .to_string(), ))) } fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) { let value = HeaderValue::from_str(&self.0).unwrap(); values.extend(std::iter::once(value)); } }