use std::collections::hash_map::DefaultHasher;
use std::collections::BinaryHeap;
use std::convert::TryFrom;
use std::hash::{Hash, Hasher};
use crate::component::{body::Body, info::Info};
use crate::plugin::deser::*;
use http::{header::HeaderName, Extensions, HeaderMap, HeaderValue};
use serde::{Deserialize, Serialize};
use std::fmt;
#[derive(Deserialize, Default, Serialize)]
pub struct Affix {
pub(crate) inner: InnerAffix,
pub(crate) body: Body,
pub(crate) metap: MetaAffix,
}
#[derive(Deserialize, Default, Serialize)]
pub struct MetaAffix {
pub info: Info,
#[serde(skip)]
pub exts: Extensions,
}
impl Hash for MetaAffix {
fn hash<H: Hasher>(&self, state: &mut H) {
self.info.used.hash(state);
self.info.marker.hash(state);
}
}
impl fmt::Debug for Affix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Affix")
.field("headers", &self.inner.headers)
.field("body", &self.body)
.field("metap", &self.metap)
.finish()
}
}
impl fmt::Debug for MetaAffix {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("MetaAffix")
.field("info", &self.info)
.finish()
}
}
impl Affix {
pub fn builder() -> AffixBuilder {
AffixBuilder::new()
}
pub fn headers(&self) -> &HeaderMap<HeaderValue> {
&self.inner.headers
}
pub fn headers_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.inner.headers
}
pub fn exts(&self) -> &Extensions {
&self.metap.exts
}
pub fn exts_mut(&mut self) -> &mut Extensions {
&mut self.metap.exts
}
pub fn rank(&self) -> i16 {
self.metap.info.rank
}
pub fn rank_mut(&mut self) -> &mut i16 {
&mut self.metap.info.rank
}
pub fn body_mut(&mut self) -> &mut Body {
&mut self.body
}
pub fn body(&self) -> &Body {
&self.body
}
pub fn into_body(self) -> Body {
self.body
}
pub fn map<F>(self, f: F) -> Affix
where
F: FnOnce(Body) -> Body,
{
Affix {
body: f(self.body),
metap: self.metap,
inner: self.inner,
}
}
pub fn from_parts(headers: HeaderMap<HeaderValue>, body: Body, metap: MetaAffix) -> Self {
let inn = InnerAffix {
headers,
extensions: Extensions::new(),
};
Self {
inner: inn,
body,
metap,
}
}
pub fn into_parts(self) -> (InnerAffix, Body, MetaAffix) {
(self.inner, self.body, self.metap)
}
}
impl Hash for Affix {
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner.hash(state);
self.metap.hash(state);
self.body.hash(state);
}
}
#[derive(Serialize, Deserialize, Default)]
pub struct InnerAffix {
#[serde(with = "serde_headermap")]
pub headers: HeaderMap<HeaderValue>,
#[serde(skip)]
pub extensions: Extensions,
}
impl Hash for InnerAffix {
fn hash<H: Hasher>(&self, state: &mut H) {
let mut heap: BinaryHeap<(&str, &str)> = BinaryHeap::new();
self.headers.iter().for_each(|(k, v)| {
heap.push((k.as_str(), v.to_str().unwrap()));
});
while let Some((k, v)) = heap.pop() {
k.hash(state);
v.hash(state);
}
}
}
pub struct AffixBuilder {
inner: InnerAffix,
meta: MetaAffix,
}
impl AffixBuilder {
pub fn new() -> Self {
Self {
inner: InnerAffix::default(),
meta: MetaAffix::default(),
}
}
pub fn header_ref(&self) -> &HeaderMap<HeaderValue> {
&self.inner.headers
}
pub fn header_mut(&mut self) -> &mut HeaderMap<HeaderValue> {
&mut self.inner.headers
}
pub fn header<K, V>(mut self, key: K, value: V) -> Self
where
HeaderName: TryFrom<K>,
<HeaderName as TryFrom<K>>::Error: Into<http::Error>,
HeaderValue: TryFrom<V>,
<HeaderValue as TryFrom<V>>::Error: Into<http::Error>,
{
let k: HeaderName = TryFrom::try_from(key)
.map_err(Into::into)
.expect("Invalid Key When Setting Header");
let v: HeaderValue = TryFrom::try_from(value)
.map_err(Into::into)
.expect("Invalid Value When Setting Header");
self.inner.headers.append(k, v);
self
}
pub fn extensions_ref(&self) -> &Extensions {
&self.inner.extensions
}
pub fn extension_mut(&mut self) -> &mut Extensions {
&mut self.inner.extensions
}
pub fn extensions<S>(mut self, extension: S) -> Self
where
S: std::any::Any + Send + Sync + 'static,
{
self.inner.extensions.insert(extension);
self
}
pub fn exts_ref(&self) -> &Extensions {
&self.meta.exts
}
pub fn exts_mut(&mut self) -> &mut Extensions {
&mut self.meta.exts
}
pub fn exts<S>(mut self, exts: S) -> Self
where
S: std::any::Any + Send + Sync + 'static,
{
self.meta.exts.insert(exts);
self
}
pub fn info_ref(&self) -> &Info {
&self.meta.info
}
pub fn info_mut(&mut self) -> &mut Info {
&mut self.meta.info
}
pub fn info<S>(mut self, info: Info) -> Self {
self.meta.info = info;
self
}
pub fn body(mut self, body: Body) -> http::Result<Affix> {
if self.meta.info.id == 0 {
let mut hasher = DefaultHasher::new();
self.inner.hash(&mut hasher);
self.meta.hash(&mut hasher);
body.hash(&mut hasher);
self.meta.info.id = hasher.finish();
}
Ok(Affix {
inner: self.inner,
metap: self.meta,
body,
})
}
pub fn meta_ref(&self) -> &MetaAffix {
&self.meta
}
pub fn meta(mut self, meta: MetaAffix) -> Self {
self.meta = meta;
self
}
}