[−][src]Struct mail::HeaderMap
A header map is a collection representing a number of mail headers in an specific order.
Example
// just import all headers use mail_headers::HeaderMap; use mail_headers::headers::*; use mail_headers::error::ComponentCreationError; fn create_headers() -> Result<HeaderMap, ComponentCreationError> { headers!{ // from and to can have multiple values // until specialization is stable is array // is necessary _From: [("My Fancy Display Name", "theduck@example.com")], _To: [ "unknown@example.com", ], Subject: "Who are you?" } } fn main() { let headers = create_headers().unwrap(); assert_eq!(headers.len(), 3); }
Note
A number of methods implemented on HeaderMap appear in two variations,
one which accepts a type hint (a normally zero sized struct implementing
HeaderKind) and on which just accepts the type and needs to be called with
the turbofish operator. The later one is prefixed by a _
as the former
one is more nice to use, but in some situations, e.g. when wrapping
HeaderMap
in custom code the only type accepting variations are more
useful.
let _ = map.get(Subject); //is equivalent to let _ = map._get::<Subject>();
MaxOne (In-)Consistency
Most headers can only appear up to one time in a header section.
They are marked with H::MAX_ONE == true
and implement MaxOneMarker
,
also as object you can use is_max_one
to check it.
Not only can they only appear max one time, it is normal for a user
who is not aware about the other headers to expect that when you insert
them into a header map which already contains them that they replace
the existing header. Even more so most headers which can appear more
then one time are unlikely to appear in a application of this library
like e.g. all Resent-*
header which normally get just prepended
to existing mail in text format or the Comment
header which isn't
used that much.
Because of this it was decided that when inserting a "max one"
header
it will act as expected an replace other headers with the same name and
only if a "multi"
header is inserted it is added to all headers associated
with the same name.
But there is a single problem. If there are multiple implementations implementations
for the same header which disagree in wether or not the header is "max one"
(which
would be a bug anyway!) then this can lead to a tricky situration when you first
insert the version which is "max one"
and then the one which is "multi"
.
There had been two ways to deal with this:
- return a error when inserting in such a situation
- simple allow it and check it when running the other validators
Given that a header map contains additionally validators which needs to be run explicitly to make sure that a map is valid before using it as a header section in a mail it was decided to go with the later approach. Originally the first approach was implemented but turned out to be not very ergonomic, and the second approach has little disadvantages as:
- it's already unlikely to run into the situation
- you have to run validators anyway before using the header map
So yes, you can not relay on the "max one" constraints to be uphold without running the validators
Methods
impl HeaderMap
[src]
pub fn new() -> HeaderMap
[src]
create a new empty header map
pub fn len(&self) -> usize
[src]
returns the number of headers in this map
pub fn clear(&mut self)
[src]
clears the header map
This removes all headers and all validators
pub fn values(&self) -> Values<HeaderName, Box<dyn HeaderObjTrait + 'static>>
[src]
Iterate over all HeaderObj
added to the map.
pub fn values_mut(
&mut self
) -> ValuesMut<HeaderName, Box<dyn HeaderObjTrait + 'static>>
[src]
&mut self
) -> ValuesMut<HeaderName, Box<dyn HeaderObjTrait + 'static>>
Iterate with mut refs over all HeaderObj
added to the map.
pub fn use_contextual_validators(&self) -> Result<(), HeaderValidationError>
[src]
call each unique contextual validator exactly once with this map as parameter
If multiple Headers provide the same contextual validator (e.g. the resent headers) it's still only called once.
Max One
This will also validate that for any header name for which a header
was added with MAX_ONE == true
it will be validated that it is the
only header for that header name.
pub fn contains<H>(&self, name: H) -> bool where
H: HasHeaderName,
[src]
H: HasHeaderName,
Returns true if this map contains a header with the given name.
pub fn get_single<H>(
&'a self,
_type_hint: H
) -> Option<Result<&'a Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
[src]
&'a self,
_type_hint: H
) -> Option<Result<&'a Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
Returns the single header associated with the given header kind.
As this uses the MaxOneMarker
trait which should only be implemented
for HeaderKind
impl with MAX_ONE == true
this function can only
be used when it's fine to ignore the possible case of more than
one header of the given kind being in the same map.
Type Hint
The type hint passed in is for ergonomics, e.g. so
that it's possible to write code like map.get_single(Subject)
if this gets in the way _get_single
can be used which would
lead to code like map._get_single::<Subject>()
.
Error
-
If there are multiple implementations for the same header and the inserted headers is based on a different type some
HeaderTypeError
is returned -
If there are multiple implementations for the same header which disagree on the value of
H::MAX_ONE
(which is a bug) this can in some rare situations lead to be there more then one header for a "max one" header in the map, in which case aHeaderTypeError
is returned.
pub fn _get_single<H>(
&'a self
) -> Option<Result<&'a Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
[src]
&'a self
) -> Option<Result<&'a Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
A variation of get_single
which doesn't require passing in a type hint.
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_mut<H>(
&mut self,
_type_hint: H
) -> Option<Result<&mut Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
[src]
&mut self,
_type_hint: H
) -> Option<Result<&mut Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
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,
[src]
&mut self
) -> Option<Result<&mut Header<H>, HeaderTypeError>> where
H: MaxOneMarker,
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_untyped<H>(
&self,
name: H
) -> EntryValues<dyn HeaderObjTrait + 'static> where
H: HasHeaderName,
[src]
&self,
name: H
) -> EntryValues<dyn HeaderObjTrait + 'static> where
H: HasHeaderName,
Returns all header bodies for a given header name, without trying to cast them to a concrete type
Accepts both HeaderName
or a type implementing HeaderKind
.
pub fn get_untyped_mut<H>(
&mut self,
name: H
) -> EntryValuesMut<dyn HeaderObjTrait + 'static> where
H: HasHeaderName,
[src]
&mut self,
name: H
) -> EntryValuesMut<dyn HeaderObjTrait + 'static> where
H: HasHeaderName,
Returns all header bodies for a given header name, without trying to cast them to a concrete type
Accepts both HeaderName
or a type implementing HeaderKind
.
ⓘImportant traits for TypedBodies<'a, H>pub fn get<H>(&self, _type_hint: H) -> TypedBodies<H> where
H: HeaderKind,
[src]
H: HeaderKind,
Returns all header bodies for a given header
ⓘImportant traits for TypedBodies<'a, H>pub fn _get<H>(&self) -> TypedBodies<H> where
H: HeaderKind,
[src]
H: HeaderKind,
Returns all header bodies for a given header
ⓘImportant traits for TypedBodiesMut<'a, H>pub fn get_mut<H>(&mut self, _type_hint: H) -> TypedBodiesMut<H> where
H: HeaderKind,
[src]
H: HeaderKind,
Returns all header bodies for a given header
ⓘImportant traits for TypedBodiesMut<'a, H>pub fn _get_mut<H>(&mut self) -> TypedBodiesMut<H> where
H: HeaderKind,
[src]
H: HeaderKind,
Returns all header bodies for a given header
pub fn insert<H>(&mut self, header: Header<H>) where
H: HeaderKind,
[src]
H: HeaderKind,
Inserts the given header into the map either replacing or adding to existing headers.
-
If
H::MAX_ONE
istrue
then it will use "replacing insert" which means all headers previously associated with the given header (name) are removed when adding the new header.This behavior is analog to how a normal map works and is what a user which isn't aware that there are some headers which can appear multiple times would expect. Most common headers (
Subject
,From
,To
,Sender
, etc.) fall into this category. -
If
H::MAX_ONE
isfalse
then it will use "adding insert" which means that it will add the header to all headers previously associated with the given header name.
pub fn insert_all(&mut self, other: HeaderMap)
[src]
Insert all given headers in order into this header map.
The insertion order of the given headers into this map is the same as the order in which they had been inserted into the header map through which they had been given to this method.
As this uses insertion it also means that headers with
MAX_ONE == true
in the headers to insert can replace
existing headers associated with the same header name.
Example
use mail_headers::headers::*; let mut map = headers!{ _From: [("Not Met", "it.s.me@example.com")], Subject: "..." }.unwrap(); map.insert_all(headers! { _To: [("You", "someone@example.com")], Subject: "expected subject" }.unwrap()); assert_eq!(map.len(), 3); let subject = map.get_single(Subject) .expect("Subject to be in map (Some)") .expect("The type to be correct (Ok)"); assert_eq!(subject.as_str(), "expected subject"); assert!(map.contains(_From)); assert!(map.contains(_To));
pub fn remove<H>(&mut self, name: H) -> bool where
H: HasHeaderName,
[src]
H: HasHeaderName,
Remove all headers with the given header name.
Returns true, if at last one header was removed.
pub fn iter(&self) -> Iter<HeaderName, Box<dyn HeaderObjTrait + 'static>>
[src]
iterate over all (header name, boxed body) pairs in this map
Trait Implementations
impl IntoIterator for HeaderMap
[src]
type Item = (HeaderName, Box<dyn HeaderObjTrait + 'static>)
The type of the elements being iterated over.
type IntoIter = IntoIter<(HeaderName, Box<dyn HeaderObjTrait + 'static>)>
Which kind of iterator are we turning this into?
fn into_iter(self) -> <HeaderMap as IntoIterator>::IntoIter
[src]
impl Clone for HeaderMap
[src]
fn clone(&self) -> HeaderMap
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl Default for HeaderMap
[src]
impl Debug for HeaderMap
[src]
Auto Trait Implementations
Blanket Implementations
impl<T> From for T
[src]
impl<I> IntoIterator for I where
I: Iterator,
[src]
I: Iterator,
type Item = <I as Iterator>::Item
The type of the elements being iterated over.
type IntoIter = I
Which kind of iterator are we turning this into?
fn into_iter(self) -> I
[src]
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = !
try_from
)The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
try_from
)The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<F, T> HeaderTryInto for F where
T: HeaderTryFrom<F>,
[src]
T: HeaderTryFrom<F>,