mail_headers/header_components/
phrase_list.rs1use soft_ascii_string::SoftAsciiChar;
2
3use vec1::{Vec1, Size0Error};
4
5use internals::error::EncodingError;
6use internals::encoder::{EncodingWriter, EncodableInHeader};
7use ::{HeaderTryFrom, HeaderTryInto};
8use ::error::ComponentCreationError;
9
10
11use super::Phrase;
12
13
14#[derive(Debug, Clone, Hash, Eq, PartialEq)]
15pub struct PhraseList(pub Vec1<Phrase>);
16
17impl IntoIterator for PhraseList {
18 type Item = <Vec1<Phrase> as IntoIterator>::Item;
19 type IntoIter = <Vec1<Phrase> as IntoIterator>::IntoIter;
20
21 fn into_iter(self) -> Self::IntoIter {
22 self.0.into_iter()
23 }
24}
25
26
27impl EncodableInHeader for PhraseList {
28
29 fn encode(&self, handle: &mut EncodingWriter) -> Result<(), EncodingError> {
30 sep_for!{ word in self.0.iter();
31 sep {
32 handle.write_char( SoftAsciiChar::from_unchecked(',') )?;
37 handle.write_char( SoftAsciiChar::from_unchecked(' ') )?;
38 };
39 word.encode( handle )?;
40
41 }
42
43 Ok( () )
44 }
45
46 fn boxed_clone(&self) -> Box<EncodableInHeader> {
47 Box::new(self.clone())
48 }
49}
50
51impl<T> HeaderTryFrom<T> for PhraseList
52 where T: HeaderTryInto<Phrase>
53{
54 fn try_from( phrase: T ) -> Result<Self, ComponentCreationError> {
55 let phrase = phrase.try_into()?;
56 Ok( PhraseList( Vec1::new( phrase ) ) )
57 }
58}
59
60
61impl<T> HeaderTryFrom<Vec<T>> for PhraseList
62 where T: HeaderTryInto<Phrase>
63{
64 fn try_from(vec: Vec<T>) -> Result<Self, ComponentCreationError> {
65 try_from_into_iter( vec )
66 }
67}
68
69fn try_from_into_iter<IT>( phrases: IT ) -> Result<PhraseList, ComponentCreationError>
70 where IT: IntoIterator, IT::Item: HeaderTryInto<Phrase>
71{
72 let mut iter = phrases.into_iter();
73 let mut vec = if let Some( first) = iter.next() {
74 Vec1::new( first.try_into()? )
75 } else {
76 return Err(
77 ComponentCreationError
78 ::from_parent(Size0Error, "PhraseList")
79 );
80 };
81 for phrase in iter {
82 vec.push( phrase.try_into()? );
83 }
84 Ok( PhraseList( vec ) )
85}
86
87macro_rules! impl_header_try_from_array {
90 (_MBoxList 0) => ();
91 (_MBoxList $len:tt) => (
92 impl<T> HeaderTryFrom<[T; $len]> for PhraseList
93 where T: HeaderTryInto<Phrase>
94 {
95 fn try_from( vec: [T; $len] ) -> Result<Self, ComponentCreationError> {
96 let heapified: Box<[T]> = Box::new(vec);
98 let vecified: Vec<_> = heapified.into();
99 try_from_into_iter( vecified )
100 }
101 }
102 );
103 ($($len:tt)*) => ($(
104 impl_header_try_from_array!{ _MBoxList $len }
105 )*);
106}
107
108impl_header_try_from_array! {
109 0 1 2 3 4 5 6 7 8 9
110 10 11 12 13 14 15 16 17 18 19
111 20 21 22 23 24 25 26 27 28 29
112 30 31 32
113}
114
115#[cfg(test)]
116mod test {
117 use super::*;
118
119 ec_test!{ some_phrases, {
120 PhraseList( vec1![
121 Phrase::try_from( "hy there" )?,
122 Phrase::try_from( "magic man" )?
123 ])
124 } => ascii => [
125 Text "hy",
126 MarkFWS,
127 Text " there, magic",
130 MarkFWS,
131 Text " man"
132 ]}
133
134 ec_test!{ some_simple_phrases_try_from, {
135 PhraseList::try_from(
136 "hy there"
137 )?
138 } => ascii => [
139 Text "hy",
140 MarkFWS,
141 Text " there"
142 ]}
143
144 ec_test!{ some_phrases_try_from, {
145 PhraseList::try_from( [
146 "hy there",
147 "magic man"
148 ] )?
149 } => ascii => [
150 Text "hy",
151 MarkFWS,
152 Text " there, magic",
153 MarkFWS,
154 Text " man"
155 ]}
156}
157