From 652d6f0ffeee7302a2cb51059bef75d8b0bb50be Mon Sep 17 00:00:00 2001 From: Philipp Korber Date: Fri, 16 Nov 2018 15:46:43 +0100 Subject: refactor: merged sources of mail-headers,mail-internals,mail-core, mail Originally it was palaned to do a merge with `--allow-unrelated-history` but this can not be doesn as `mail-core` has a "invalid" history which has a merge conflict **with itself**. So even rewinding the history on a empty repo is not possible. Instead the code was directly coppied over losing history. But the history is still available in the different `history-backup-*` branches. It is just that the past history is decoupled from the current history. --- headers/src/header_components/phrase_list.rs | 157 +++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 headers/src/header_components/phrase_list.rs (limited to 'headers/src/header_components/phrase_list.rs') 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); + +impl IntoIterator for PhraseList { + type Item = as IntoIterator>::Item; + type IntoIter = 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 { + Box::new(self.clone()) + } +} + +impl HeaderTryFrom for PhraseList + where T: HeaderTryInto +{ + fn try_from( phrase: T ) -> Result { + let phrase = phrase.try_into()?; + Ok( PhraseList( Vec1::new( phrase ) ) ) + } +} + + +impl HeaderTryFrom> for PhraseList + where T: HeaderTryInto +{ + fn try_from(vec: Vec) -> Result { + try_from_into_iter( vec ) + } +} + +fn try_from_into_iter( phrases: IT ) -> Result + where IT: IntoIterator, IT::Item: HeaderTryInto +{ + 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 HeaderTryFrom<[T; $len]> for PhraseList + where T: HeaderTryInto + { + fn try_from( vec: [T; $len] ) -> Result { + //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" + ]} +} + -- cgit v1.2.3