use std::ops::Deref;
use std::sync::Arc;
use serde::de::DeserializeOwned;
use super::{NegotiateResponse, NegotiatedFormat};
use crate::format::ErasedFormat;
pub struct Negotiate<T: DeserializeOwned> {
value: T,
format: Arc<dyn ErasedFormat>,
}
impl<T: DeserializeOwned> Negotiate<T> {
pub fn new(value: T, format: Arc<dyn ErasedFormat>) -> Self {
Self { value, format }
}
pub fn respond<U: serde::Serialize>(&self, value: U) -> NegotiateResponse<U> {
NegotiateResponse::new(value, Arc::clone(&self.format))
}
pub fn format(&self) -> &Arc<dyn ErasedFormat> {
&self.format
}
pub fn into_inner(self) -> T {
self.value
}
}
impl<T: DeserializeOwned> Deref for Negotiate<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.value
}
}
impl<T: DeserializeOwned + std::fmt::Debug> std::fmt::Debug for Negotiate<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Negotiate")
.field("value", &self.value)
.field("format", &self.format)
.finish()
}
}
pub fn extract_negotiated_format(extensions: &http::Extensions) -> Option<&NegotiatedFormat> {
extensions.get::<NegotiatedFormat>()
}