diff options
Diffstat (limited to 'headers/src/header_components/phrase_list.rs')
-rw-r--r-- | headers/src/header_components/phrase_list.rs | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/headers/src/header_components/phrase_list.rs b/headers/src/header_components/phrase_list.rs new file mode 100644 index 0000000..4f107b9 --- /dev/null +++ b/headers/src/header_components/phrase_list.rs @@ -0,0 +1,157 @@ +use soft_ascii_string::SoftAsciiChar; + +use vec1::{Vec1, Size0Error}; + +use internals::error::EncodingError; +use internals::encoder::{EncodingWriter, EncodableInHeader}; +use ::{HeaderTryFrom, HeaderTryInto}; +use ::error::ComponentCreationError; + + +use super::Phrase; + + +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +pub struct PhraseList(pub Vec1<Phrase>); + +impl IntoIterator for PhraseList { + type Item = <Vec1<Phrase> as IntoIterator>::Item; + type IntoIter = <Vec1<Phrase> as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + + +impl EncodableInHeader for PhraseList { + + fn encode(&self, handle: &mut EncodingWriter) -> Result<(), EncodingError> { + sep_for!{ word in self.0.iter(); + sep { + //TODO handle this better by collapsing FWS + // <= isn't that allready fixed by FWS+ has content on line in EncodingBuffer + //Note that we do not want to write FWS as the following word might contains + // a left_padding with a MarkFWS, NowChar, Text " " but a space if fine + handle.write_char( SoftAsciiChar::from_unchecked(',') )?; + handle.write_char( SoftAsciiChar::from_unchecked(' ') )?; + }; + word.encode( handle )?; + + } + + Ok( () ) + } + + fn boxed_clone(&self) -> Box<EncodableInHeader> { + Box::new(self.clone()) + } +} + +impl<T> HeaderTryFrom<T> for PhraseList + where T: HeaderTryInto<Phrase> +{ + fn try_from( phrase: T ) -> Result<Self, ComponentCreationError> { + let phrase = phrase.try_into()?; + Ok( PhraseList( Vec1::new( phrase ) ) ) + } +} + + +impl<T> HeaderTryFrom<Vec<T>> for PhraseList + where T: HeaderTryInto<Phrase> +{ + fn try_from(vec: Vec<T>) -> Result<Self, ComponentCreationError> { + try_from_into_iter( vec ) + } +} + +fn try_from_into_iter<IT>( phrases: IT ) -> Result<PhraseList, ComponentCreationError> + where IT: IntoIterator, IT::Item: HeaderTryInto<Phrase> +{ + let mut iter = phrases.into_iter(); + let mut vec = if let Some( first) = iter.next() { + Vec1::new( first.try_into()? ) + } else { + return Err( + ComponentCreationError + ::from_parent(Size0Error, "PhraseList") + ); + }; + for phrase in iter { + vec.push( phrase.try_into()? ); + } + Ok( PhraseList( vec ) ) +} + +//FIXME: dedup code duplication with: +// MailboxList, PhraseList(this think here) and ?? possible future types?? +macro_rules! impl_header_try_from_array { + (_MBoxList 0) => (); + (_MBoxList $len:tt) => ( + impl<T> HeaderTryFrom<[T; $len]> for PhraseList + where T: HeaderTryInto<Phrase> + { + fn try_from( vec: [T; $len] ) -> Result<Self, ComponentCreationError> { + //due to only supporting arrays halfheartedly for now + let heapified: Box<[T]> = Box::new(vec); + let vecified: Vec<_> = heapified.into(); + try_from_into_iter( vecified ) + } + } + ); + ($($len:tt)*) => ($( + impl_header_try_from_array!{ _MBoxList $len } + )*); +} + +impl_header_try_from_array! { + 0 1 2 3 4 5 6 7 8 9 + 10 11 12 13 14 15 16 17 18 19 + 20 21 22 23 24 25 26 27 28 29 + 30 31 32 +} + +#[cfg(test)] +mod test { + use super::*; + + ec_test!{ some_phrases, { + PhraseList( vec1![ + Phrase::try_from( "hy there" )?, + Phrase::try_from( "magic man" )? + ]) + } => ascii => [ + Text "hy", + MarkFWS, + //TODO really no FWS by the seperator?? + // (currently it's this way as word can start with a FWS making it a double FWS) + Text " there, magic", + MarkFWS, + Text " man" + ]} + + ec_test!{ some_simple_phrases_try_from, { + PhraseList::try_from( + "hy there" + )? + } => ascii => [ + Text "hy", + MarkFWS, + Text " there" + ]} + + ec_test!{ some_phrases_try_from, { + PhraseList::try_from( [ + "hy there", + "magic man" + ] )? + } => ascii => [ + Text "hy", + MarkFWS, + Text " there, magic", + MarkFWS, + Text " man" + ]} +} + |