#[cfg(feature = "proxy")]
use crate::component::proxy::{Auth, AuthBasic, AuthBearer, AuthCustom, Proxy};
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,
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub(crate) proxy: Option<Proxy>,
}
#[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 {
let mut fmter = f.debug_struct("Affix");
fmter
.field("headers", &self.inner.headers)
.field("body", &self.body)
.field("metap", &self.metap);
#[cfg(feature = "proxy")]
fmter.field("proxy", &self.proxy());
fmter.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
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_mut(&mut self) -> Option<&mut Proxy> {
self.proxy.as_mut()
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy(&self) -> Option<&Proxy> {
self.proxy.as_ref()
}
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,
#[cfg(feature = "proxy")]
proxy: self.proxy,
}
}
pub fn from_parts(
inner: InnerAffix,
body: Body,
metap: MetaAffix,
#[cfg(feature = "proxy")] proxy: Option<Proxy>,
) -> Self {
Self {
inner,
body,
metap,
#[cfg(feature = "proxy")]
proxy,
}
}
#[cfg(not(feature = "proxy"))]
pub fn into_parts(self) -> (InnerAffix, Body, MetaAffix) {
(self.inner, self.body, self.metap)
}
#[cfg(feature = "proxy")]
pub fn into_parts(self) -> (InnerAffix, Body, MetaAffix, Option<Proxy>) {
return (self.inner, self.body, self.metap, self.proxy);
}
}
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,
#[cfg(feature = "proxy")]
proxy: Option<Proxy>,
}
impl AffixBuilder {
pub fn new() -> Self {
Self {
inner: InnerAffix::default(),
meta: MetaAffix::default(),
#[cfg(feature = "proxy")]
proxy: None,
}
}
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,
#[cfg(feature = "proxy")]
proxy: self.proxy,
})
}
pub fn meta_ref(&self) -> &MetaAffix {
&self.meta
}
pub fn meta(mut self, meta: MetaAffix) -> Self {
self.meta = meta;
self
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_mut(&mut self) -> Option<&mut Proxy> {
self.proxy.as_mut()
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy<T: Into<String>>(mut self, addr: T) {
self.proxy = Some(Proxy {
addr: addr.into(),
auth: None,
});
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_auth_basic<T: Into<String>>(mut self, addr: T, username: T, password: T) {
self.proxy = Some(Proxy {
addr: addr.into(),
auth: Some(Auth::Basic(AuthBasic {
username: username.into(),
password: password.into(),
})),
});
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_auth_bearer<T: Into<String>>(mut self, addr: T, bearer: T) {
self.proxy = Some(Proxy {
addr: addr.into(),
auth: Some(Auth::Bearer(AuthBearer {
bearer: bearer.into(),
})),
});
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_auth_custom<T: Into<String>>(mut self, addr: T, token: T) {
self.proxy = Some(Proxy {
addr: addr.into(),
auth: Some(Auth::Custom(AuthCustom {
token: token.into(),
})),
});
}
#[cfg_attr(docsrs, doc(cfg(feature = "proxy")))]
#[cfg(feature = "proxy")]
pub fn proxy_ref(&self) -> Option<&Proxy> {
self.proxy.as_ref()
}
}