summaryrefslogtreecommitdiffstats
path: root/headers/src/map/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'headers/src/map/mod.rs')
-rw-r--r--headers/src/map/mod.rs283
1 files changed, 144 insertions, 139 deletions
diff --git a/headers/src/map/mod.rs b/headers/src/map/mod.rs
index 7718bd3..0d355b9 100644
--- a/headers/src/map/mod.rs
+++ b/headers/src/map/mod.rs
@@ -2,35 +2,20 @@
//!
//! It also contains some helper types like iterator types
//! for the HeaderMap etc.
-use std::marker::PhantomData;
-use std::iter::ExactSizeIterator;
-use std::fmt::{self, Debug};
-use std::collections::HashSet;
use std::cmp::PartialEq;
+use std::collections::HashSet;
+use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher};
+use std::iter::ExactSizeIterator;
+use std::marker::PhantomData;
+
+use total_order_multi_map::{self, EntryValues, EntryValuesMut, TotalOrderMultiMap};
+
+use error::{BuildInValidationError, HeaderTypeError, HeaderValidationError};
+
+use name::{HasHeaderName, HeaderName};
-use total_order_multi_map::{
- self,
- TotalOrderMultiMap,
- EntryValues,
- EntryValuesMut
-};
-
-use ::error::{
- HeaderTypeError,
- HeaderValidationError,
- BuildInValidationError
-};
-
-use ::name::{
- HeaderName, HasHeaderName
-};
-
-use ::header::{
- Header, HeaderKind,
- HeaderObj, HeaderObjTrait,
- MaxOneMarker
-};
+use header::{Header, HeaderKind, HeaderObj, HeaderObjTrait, MaxOneMarker};
mod into_iter;
pub use self::into_iter::*;
@@ -158,13 +143,12 @@ impl Debug for HeaderMap {
impl Default for HeaderMap {
fn default() -> Self {
HeaderMap {
- inner_map: Default::default()
+ inner_map: Default::default(),
}
}
}
impl HeaderMap {
-
/// create a new empty header map
pub fn new() -> Self {
Default::default()
@@ -215,13 +199,15 @@ impl HeaderMap {
};
for mut group in self.inner_map.group_iter() {
- let first = group.next().expect("[BUG] returned header without any headers inserted for it");
+ let first = group
+ .next()
+ .expect("[BUG] returned header without any headers inserted for it");
let max_one = first.is_max_one();
validate(first.validator())?;
let header_name = group.key().as_str();
for other in group {
if max_one != other.is_max_one() {
- return Err(BuildInValidationError::MaxOneInconsistency { header_name }.into());
+ return Err(BuildInValidationError::MaxOneInconsistency { header_name }.into());
}
validate(other.validator())?;
}
@@ -260,9 +246,12 @@ impl HeaderMap {
/// a "max one" header in the map, in which case a `HeaderTypeError`
/// is returned.
#[inline]
- pub fn get_single<'a, H>(&'a self, _type_hint: H)
- -> Option<Result<&'a Header<H>, HeaderTypeError>>
- where H: MaxOneMarker
+ pub fn get_single<'a, H>(
+ &'a self,
+ _type_hint: H,
+ ) -> Option<Result<&'a Header<H>, HeaderTypeError>>
+ where
+ H: MaxOneMarker,
{
self._get_single::<H>()
}
@@ -271,17 +260,18 @@ impl HeaderMap {
///
/// Normally using `get_single` is more ergonomic, except if you write a function
/// which abstracts over it in which case using `_get_single` can be better.
- pub fn _get_single<'a, H>(&'a self)
- -> Option<Result<&'a Header<H>, HeaderTypeError>>
- where H: MaxOneMarker
+ pub fn _get_single<'a, H>(&'a self) -> Option<Result<&'a Header<H>, HeaderTypeError>>
+ where
+ H: MaxOneMarker,
{
let mut bodies = self.get_untyped(H::name());
if bodies.len() > 1 {
- return Some(Err(HeaderTypeError::new(H::name())))
+ return Some(Err(HeaderTypeError::new(H::name())));
}
bodies.next().map(|untyped| {
- untyped.downcast_ref::<H>()
+ untyped
+ .downcast_ref::<H>()
.ok_or_else(|| HeaderTypeError::new(H::name()))
})
}
@@ -290,9 +280,12 @@ impl HeaderMap {
///
/// See `HeaderMap::get_single` for more details.
#[inline]
- pub fn get_single_mut<H>(&mut self, _type_hint: H)
- -> Option<Result<&mut Header<H>, HeaderTypeError>>
- where H: MaxOneMarker
+ pub fn get_single_mut<H>(
+ &mut self,
+ _type_hint: H,
+ ) -> Option<Result<&mut Header<H>, HeaderTypeError>>
+ where
+ H: MaxOneMarker,
{
self._get_single_mut::<H>()
}
@@ -300,17 +293,18 @@ impl HeaderMap {
/// Returns a a mutable reference to the header associated with the given header kind.__internals
///
/// See `HeaderMap::_get_single` for more details.
- pub fn _get_single_mut<H>(&mut self)
- -> Option<Result<&mut Header<H>, HeaderTypeError>>
- where H: MaxOneMarker
+ pub fn _get_single_mut<H>(&mut self) -> Option<Result<&mut Header<H>, HeaderTypeError>>
+ where
+ H: MaxOneMarker,
{
let mut bodies = self.get_untyped_mut(H::name());
if bodies.len() > 1 {
- return Some(Err(HeaderTypeError::new(H::name())))
+ return Some(Err(HeaderTypeError::new(H::name())));
}
bodies.next().map(|untyped| {
- untyped.downcast_mut::<H>()
+ untyped
+ .downcast_mut::<H>()
.ok_or_else(|| HeaderTypeError::new(H::name()))
})
}
@@ -336,14 +330,16 @@ impl HeaderMap {
/// Returns all header bodies for a given header
#[inline(always)]
pub fn get<H>(&self, _type_hint: H) -> TypedBodies<H>
- where H: HeaderKind
+ where
+ H: HeaderKind,
{
self._get::<H>()
}
/// Returns all header bodies for a given header
pub fn _get<H>(&self) -> TypedBodies<H>
- where H: HeaderKind
+ where
+ H: HeaderKind,
{
self.get_untyped(H::name()).into()
}
@@ -351,14 +347,16 @@ impl HeaderMap {
/// Returns all header bodies for a given header
#[inline(always)]
pub fn get_mut<H>(&mut self, _type_hint: H) -> TypedBodiesMut<H>
- where H: HeaderKind
+ where
+ H: HeaderKind,
{
self._get_mut::<H>()
}
/// Returns all header bodies for a given header
pub fn _get_mut<H>(&mut self) -> TypedBodiesMut<H>
- where H: HeaderKind
+ where
+ H: HeaderKind,
{
self.get_untyped_mut(H::name()).into()
}
@@ -379,7 +377,8 @@ impl HeaderMap {
/// header name.
///
pub fn insert<H>(&mut self, header: Header<H>)
- where H: HeaderKind
+ where
+ H: HeaderKind,
{
let name = header.name();
let obj: Box<HeaderObj> = Box::new(header);
@@ -458,27 +457,27 @@ impl HeaderMap {
pub fn iter(&self) -> Iter {
self.inner_map.iter()
}
-
}
/// Iterator over all boxed bodies for a given header name
pub type UntypedBodies<'a> = EntryValues<'a, HeaderObj>;
pub type UntypedBodiesMut<'a> = EntryValuesMut<'a, HeaderObj>;
-
/// Iterator over all boxed bodies for a given header name with knows which type they should have
///
/// This iterator will automatically try to cast each header body of this
/// header to `H::Component`, i.e. the type this body _should_ have.
pub struct TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
inner: UntypedBodies<'a>,
- _marker: PhantomData<H>
+ _marker: PhantomData<H>,
}
impl<'a, H> From<UntypedBodies<'a>> for TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn from(untyped: UntypedBodies<'a>) -> Self {
Self::new(untyped)
@@ -486,27 +485,28 @@ impl<'a, H> From<UntypedBodies<'a>> for TypedBodies<'a, H>
}
impl<'a, H> TypedBodies<'a, H>
- where H: HeaderKind,
+where
+ H: HeaderKind,
{
fn new(inner: UntypedBodies<'a>) -> Self {
TypedBodies {
inner,
- _marker: PhantomData
+ _marker: PhantomData,
}
}
}
impl<'a, H> Iterator for TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
type Item = Result<&'a Header<H>, HeaderTypeError>;
fn next(&mut self) -> Option<Self::Item> {
- self.inner.next()
- .map( |tobj| {
- tobj.downcast_ref::<H>()
- .ok_or_else(|| HeaderTypeError::new(H::name()))
- } )
+ self.inner.next().map(|tobj| {
+ tobj.downcast_ref::<H>()
+ .ok_or_else(|| HeaderTypeError::new(H::name()))
+ })
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -515,7 +515,8 @@ impl<'a, H> Iterator for TypedBodies<'a, H>
}
impl<'a, H> ExactSizeIterator for TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn len(&self) -> usize {
self.inner.len()
@@ -523,7 +524,8 @@ impl<'a, H> ExactSizeIterator for TypedBodies<'a, H>
}
impl<'a, H> Clone for TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn clone(&self) -> Self {
TypedBodies::new(self.inner.clone())
@@ -531,7 +533,8 @@ impl<'a, H> Clone for TypedBodies<'a, H>
}
impl<'a, H> Debug for TypedBodies<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
fter.debug_struct("TypedBodies")
@@ -545,14 +548,16 @@ impl<'a, H> Debug for TypedBodies<'a, H>
/// This iterator will automatically try to cast each header body of this
/// header to `H::Component`, i.e. the type this body _should_ have.
pub struct TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
inner: UntypedBodiesMut<'a>,
- _marker: PhantomData<H>
+ _marker: PhantomData<H>,
}
impl<'a, H> From<UntypedBodiesMut<'a>> for TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn from(untyped: UntypedBodiesMut<'a>) -> Self {
Self::new(untyped)
@@ -560,27 +565,28 @@ impl<'a, H> From<UntypedBodiesMut<'a>> for TypedBodiesMut<'a, H>
}
impl<'a, H> TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn new(inner: UntypedBodiesMut<'a>) -> Self {
TypedBodiesMut {
inner,
- _marker: PhantomData
+ _marker: PhantomData,
}
}
}
impl<'a, H> Iterator for TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
type Item = Result<&'a mut Header<H>, HeaderTypeError>;
fn next(&mut self) -> Option<Self::Item> {
- self.inner.next()
- .map(|tobj| {
- tobj.downcast_mut::<H>()
- .ok_or_else(|| HeaderTypeError::new(H::name()))
- })
+ self.inner.next().map(|tobj| {
+ tobj.downcast_mut::<H>()
+ .ok_or_else(|| HeaderTypeError::new(H::name()))
+ })
}
fn size_hint(&self) -> (usize, Option<usize>) {
@@ -589,7 +595,8 @@ impl<'a, H> Iterator for TypedBodiesMut<'a, H>
}
impl<'a, H> ExactSizeIterator for TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn len(&self) -> usize {
self.inner.len()
@@ -597,7 +604,8 @@ impl<'a, H> ExactSizeIterator for TypedBodiesMut<'a, H>
}
impl<'a, H> Debug for TypedBodiesMut<'a, H>
- where H: HeaderKind
+where
+ H: HeaderKind,
{
fn fmt(&self, fter: &mut fmt::Formatter) -> fmt::Result {
fter.write_str("TypedBodiesMut { .. }")
@@ -644,7 +652,6 @@ macro_rules! headers {
struct ValidatorHashWrapper(HeaderMapValidator);
impl ValidatorHashWrapper {
-
fn identity_repr(&self) -> usize {
self.0 as usize
}
@@ -670,18 +677,18 @@ impl Hash for ValidatorHashWrapper {
}
}
-
-pub fn check_header_count_max_one(name: HeaderName, map: &HeaderMap)
- -> Result<(), HeaderValidationError>
-{
+pub fn check_header_count_max_one(
+ name: HeaderName,
+ map: &HeaderMap,
+) -> Result<(), HeaderValidationError> {
let valid = map.get_untyped(name).len() <= 1;
if valid {
Ok(())
} else {
Err(HeaderValidationError::from(
BuildInValidationError::MoreThenOne {
- header_name: name.as_str()
- }
+ header_name: name.as_str(),
+ },
))
}
}
@@ -691,23 +698,18 @@ mod test {
use failure::Context;
use soft_ascii_string::SoftAsciiStr;
- use internals::error::{EncodingError, EncodingErrorKind};
use internals::encoder::{EncodableInHeader, EncodingWriter};
+ use internals::error::{EncodingError, EncodingErrorKind};
- use ::HeaderTryFrom;
- use ::error::{ComponentCreationError, HeaderValidationError};
- use ::header_components::RawUnstructured;
+ use error::{ComponentCreationError, HeaderValidationError};
+ use header_components::RawUnstructured;
+ use HeaderTryFrom;
use super::*;
+ use self::bad_headers::{Comments as BadComments, Subject as BadSubject};
+ use self::bad_headers2::Comments2 as BadComments2;
use self::good_headers::*;
- use self::bad_headers::{
- Subject as BadSubject,
- Comments as BadComments
- };
- use self::bad_headers2::{
- Comments2 as BadComments2
- };
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct OtherComponent;
@@ -718,9 +720,10 @@ mod test {
}
}
impl EncodableInHeader for OtherComponent {
- fn encode(&self, _encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
- Err(EncodingError::from(
- EncodingErrorKind::Other { kind: "encoding is not implemented" }))
+ fn encode(&self, _encoder: &mut EncodingWriter) -> Result<(), EncodingError> {
+ Err(EncodingError::from(EncodingErrorKind::Other {
+ kind: "encoding is not implemented",
+ }))
}
fn boxed_clone(&self) -> Box<EncodableInHeader> {
@@ -728,9 +731,8 @@ mod test {
}
}
-
mod good_headers {
- use ::header_components;
+ use header_components;
def_headers! {
test_name: validate_header_names,
scope: header_components,
@@ -779,15 +781,15 @@ mod test {
let headers = headers! {
Comments: TEXT_1,
Subject: TEXT_2
- }.unwrap();
-
+ }
+ .unwrap();
let count = headers
// all headers _could_ have multiple values, through neither
// ContentType nor Subject do have multiple value
.get(Comments)
.map(|h: Result<&Header<Comments>, HeaderTypeError>| {
- let v = h.expect( "the trait object to be downcastable to Header<Comments>" );
+ let v = h.expect("the trait object to be downcastable to Header<Comments>");
assert_eq!(v.as_str(), TEXT_1);
})
.count();
@@ -796,7 +798,7 @@ mod test {
let count = headers
.get(Subject)
.map(|h: Result<&Header<Subject>, HeaderTypeError>| {
- let val = h.expect( "the trait object to be downcastable to Header<Subject>" );
+ let val = h.expect("the trait object to be downcastable to Header<Subject>");
assert_eq!(val.as_str(), TEXT_2);
})
.count();
@@ -807,13 +809,15 @@ mod test {
fn get_single() {
let headers = headers! {
Subject: "abc"
- }.unwrap();
+ }
+ .unwrap();
assert_eq!(
"abc",
- headers.get_single(Subject)
- .unwrap()//Some
- .unwrap()//Result
+ headers
+ .get_single(Subject)
+ .unwrap() //Some
+ .unwrap() //Result
.as_str()
);
}
@@ -822,10 +826,11 @@ mod test {
fn get_single_cast_error() {
let headers = headers! {
Subject: "abc"
- }.unwrap();
+ }
+ .unwrap();
let res = headers.get_single(BadSubject);
- assert_err!( res.expect("where did the header go?") );
+ assert_err!(res.expect("where did the header go?"));
}
#[test]
@@ -834,22 +839,18 @@ mod test {
Subject: "abc",
Comments: "1st",
BadComments: ()
- }.unwrap();
-
+ }
+ .unwrap();
let mut res = headers.get(Comments);
assert_eq!(res.size_hint(), (2, Some(2)));
- assert_eq!(
- "1st",
- assert_ok!(res.next().unwrap()).as_str()
- );
+ assert_eq!("1st", assert_ok!(res.next().unwrap()).as_str());
assert_err!(res.next().unwrap());
- assert!( res.next().is_none() )
-
+ assert!(res.next().is_none())
}
#[test]
@@ -858,31 +859,37 @@ mod test {
Subject: "abc",
Comments: "1st",
BadComments: ()
- }.unwrap();
-
+ }
+ .unwrap();
- let res = headers.get_untyped(Subject::name())
- .map(|entry| entry.downcast_ref::<Subject>().unwrap().as_str() )
+ let res = headers
+ .get_untyped(Subject::name())
+ .map(|entry| entry.downcast_ref::<Subject>().unwrap().as_str())
.collect::<Vec<_>>();
- assert_eq!(
- res.as_slice(),
- &[ "abc" ]
- );
+ assert_eq!(res.as_slice(), &["abc"]);
let mut res = headers.get_untyped(Comments::name());
assert_eq!((2, Some(2)), res.size_hint());
assert_eq!(
- res.next().unwrap().downcast_ref::<Comments>().unwrap().as_str(),
+ res.next()
+ .unwrap()
+ .downcast_ref::<Comments>()
+ .unwrap()
+ .as_str(),
"1st"
);
assert_eq!((1, Some(1)), res.size_hint());
assert_eq!(
- res.next().unwrap().downcast_ref::<BadComments>().unwrap().body(),
+ res.next()
+ .unwrap()
+ .downcast_ref::<BadComments>()
+ .unwrap()
+ .body(),
&OtherComponent
);
@@ -893,7 +900,8 @@ mod test {
fn fmt_debug() {
let headers = headers! {
Subject: "hy there"
- }.unwrap();
+ }
+ .unwrap();
let res = format!("{:?}", headers);
assert_eq!(
@@ -925,7 +933,6 @@ mod test {
);
});
-
test!(remove_1 {
let mut headers = headers!{
Comments: "a",
@@ -981,9 +988,8 @@ mod test {
HeaderName::new(SoftAsciiStr::from_unchecked("X-Comment")).unwrap()
}
- const VALIDATOR: Option<
- fn(&HeaderMap)-> Result<(), HeaderValidationError>
- > = Some(__validator);
+ const VALIDATOR: Option<fn(&HeaderMap) -> Result<(), HeaderValidationError>> =
+ Some(__validator);
const MAX_ONE: bool = false;
}
@@ -992,8 +998,7 @@ mod test {
fn __validator(map: &HeaderMap) -> Result<(), HeaderValidationError> {
if map.get_untyped(Comments::name()).len() != 0 {
return Err(HeaderValidationError::Custom(
- Context::new("can't have X-Comment and Comments in same mail")
- .into()
+ Context::new("can't have X-Comment and Comments in same mail").into(),
));
}
Ok(())
@@ -1049,4 +1054,4 @@ mod test {
assert_eq!(1, map.len());
});
-} \ No newline at end of file
+}