use std::any::type_name;
use std::fmt::Debug;
use std::time::Duration;
use http::Extensions;
pub(crate) trait RequestConfigValue: Copy + Clone + 'static {
type Value: Clone + Debug + Send + Sync + 'static;
}
#[derive(Clone, Copy)]
pub(crate) struct RequestConfig<T: RequestConfigValue>(Option<T::Value>);
impl<T: RequestConfigValue> Default for RequestConfig<T> {
fn default() -> Self {
RequestConfig(None)
}
}
impl<T> RequestConfig<T>
where
T: RequestConfigValue,
{
pub(crate) fn new(v: Option<T::Value>) -> Self {
RequestConfig(v)
}
pub(crate) fn fmt_as_field(&self, f: &mut std::fmt::DebugStruct<'_, '_>) {
if let Some(v) = &self.0 {
f.field(type_name::<T>(), v);
}
}
pub(crate) fn fetch<'client, 'request>(
&'client self,
ext: &'request Extensions,
) -> Option<&'request T::Value>
where
'client: 'request,
{
ext.get::<RequestConfig<T>>()
.and_then(|v| v.0.as_ref())
.or(self.0.as_ref())
}
pub(crate) fn get(ext: &Extensions) -> Option<&T::Value> {
ext.get::<RequestConfig<T>>().and_then(|v| v.0.as_ref())
}
pub(crate) fn get_mut(ext: &mut Extensions) -> &mut Option<T::Value> {
let cfg = ext.get_or_insert_default::<RequestConfig<T>>();
&mut cfg.0
}
}
#[derive(Clone, Copy)]
pub(crate) struct TotalTimeout;
impl RequestConfigValue for TotalTimeout {
type Value = Duration;
}