|
27 | 27 | //! - Version 4 [RFC 6350: vCard Format Specification](https://datatracker.ietf.org/doc/rfc6350/) |
28 | 28 | //! - Parameter escaping [RFC 6868 Parameter Value Encoding in iCalendar and vCard](https://datatracker.ietf.org/doc/rfc6868/) |
29 | 29 |
|
30 | | -use std::{collections::HashMap, convert::TryInto}; |
| 30 | +use std::convert::TryInto; |
| 31 | + |
| 32 | +use indexmap::IndexMap; |
31 | 33 |
|
32 | 34 | use super::*; |
33 | 35 | use crate::{ |
@@ -63,14 +65,14 @@ const FOOTER: &str = "END:VCARD"; |
63 | 65 |
|
64 | 66 | #[derive(Debug)] |
65 | 67 | pub struct VCard<T: VCardVersion>( |
66 | | - HashMap<String, ContentLine>, |
| 68 | + IndexMap<String, ContentLine>, |
67 | 69 | std::marker::PhantomData<*const T>, |
68 | 70 | ); |
69 | 71 |
|
70 | 72 | impl<V: VCardVersion> VCard<V> { |
71 | 73 | pub fn new_v4() -> VCard<impl VCardVersion> { |
72 | 74 | VCard( |
73 | | - HashMap::default(), |
| 75 | + IndexMap::default(), |
74 | 76 | std::marker::PhantomData::<*const VCardVersion4>, |
75 | 77 | ) |
76 | 78 | } |
@@ -106,7 +108,7 @@ impl CardDeserializer { |
106 | 108 | &input[HEADER_LF.len()..input.len() - FOOTER_LF.len()] |
107 | 109 | }; |
108 | 110 |
|
109 | | - let mut ret = HashMap::default(); |
| 111 | + let mut ret = IndexMap::default(); |
110 | 112 |
|
111 | 113 | enum Stage { |
112 | 114 | Group, |
@@ -198,15 +200,15 @@ impl<V: VCardVersion> TryInto<Card> for VCard<V> { |
198 | 200 | } |
199 | 201 | hasher.finish() |
200 | 202 | })); |
201 | | - if let Some(val) = self.0.remove("FN") { |
| 203 | + if let Some(val) = self.0.swap_remove("FN") { |
202 | 204 | card.set_name(val.value); |
203 | 205 | } else { |
204 | 206 | return Err(Error::new("FN entry missing in VCard.").set_kind(ErrorKind::ValueError)); |
205 | 207 | } |
206 | | - if let Some(val) = self.0.remove("NICKNAME") { |
| 208 | + if let Some(val) = self.0.swap_remove("NICKNAME") { |
207 | 209 | card.set_additionalname(val.value); |
208 | 210 | } |
209 | | - if let Some(val) = self.0.remove("BDAY") { |
| 211 | + if let Some(val) = self.0.swap_remove("BDAY") { |
210 | 212 | /* 4.3.4. DATE-AND-OR-TIME |
211 | 213 |
|
212 | 214 | Either a DATE-TIME, a DATE, or a TIME value. To allow unambiguous |
@@ -234,13 +236,13 @@ impl<V: VCardVersion> TryInto<Card> for VCard<V> { |
234 | 236 | crate::utils::datetime::timestamp_from_string(val.value.as_str(), "%Y%m%d\0") |
235 | 237 | .unwrap_or_default(); |
236 | 238 | } |
237 | | - if let Some(val) = self.0.remove("EMAIL") { |
| 239 | + if let Some(val) = self.0.swap_remove("EMAIL") { |
238 | 240 | card.set_email(val.value); |
239 | 241 | } |
240 | | - if let Some(val) = self.0.remove("URL") { |
| 242 | + if let Some(val) = self.0.swap_remove("URL") { |
241 | 243 | card.set_url(val.value); |
242 | 244 | } |
243 | | - if let Some(val) = self.0.remove("KEY") { |
| 245 | + if let Some(val) = self.0.swap_remove("KEY") { |
244 | 246 | card.set_key(val.value); |
245 | 247 | } |
246 | 248 | for (k, v) in self.0.into_iter() { |
|
0 commit comments