diff options
Diffstat (limited to 'headers/src/map/mod.rs')
-rw-r--r-- | headers/src/map/mod.rs | 283 |
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 +} |