// // imag - the personal information management suite for the commandline // Copyright (C) 2015-2019 Matthias Beyer and contributors // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; version // 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // use std::collections::BTreeMap; use vobject::vcard::Vcard; #[derive(Serialize, Deserialize, Debug)] pub struct Email { pub address: String, #[serde(skip_serializing_if = "BTreeMap::is_empty")] #[serde(default)] pub properties: BTreeMap, } impl From<::vobject::vcard::Email> for Email { fn from(voemail: ::vobject::vcard::Email) -> Self { let address = voemail.raw().clone(); let properties = voemail.params().clone(); Email { address, properties } } } /// A type which can be build from a Vcard and be serialized. #[derive(Serialize, Deserialize, Debug)] pub struct DeserVcard { #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] adr : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] anniversary : Option, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] bday : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] categories : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] clientpidmap : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] fullname : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] gender : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] geo : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] impp : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] key : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] lang : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] logo : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] member : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] name : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] nickname : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] note : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] org : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] photo : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] proid : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] related : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] rev : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] role : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] sound : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] tel : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] title : Vec, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] tz : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] uid : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] url : Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] version : Option, #[serde(skip_serializing_if = "Vec::is_empty")] #[serde(default)] email : Vec, } impl From for DeserVcard { fn from(card: Vcard) -> DeserVcard { macro_rules! arystr { ($v:expr) => { $v.into_iter().map(|o| o.raw().clone()).collect() }; }; macro_rules! optstr { ($o:expr) => { $o.map(|o| o.raw().clone()) }; }; DeserVcard { adr : arystr!(card.adr()), anniversary : optstr!(card.anniversary()), bday : optstr!(card.bday()), categories : arystr!(card.categories()), clientpidmap : optstr!(card.clientpidmap()), email : card.email().into_iter().map(Email::from).collect::>(), fullname : arystr!(card.fullname()), gender : optstr!(card.gender()), geo : arystr!(card.geo()), impp : arystr!(card.impp()), key : arystr!(card.key()), lang : arystr!(card.lang()), logo : arystr!(card.logo()), member : arystr!(card.member()), name : optstr!(card.name()), nickname : arystr!(card.nickname()), note : arystr!(card.note()), org : arystr!(card.org()), photo : arystr!(card.photo()), proid : optstr!(card.proid()), related : arystr!(card.related()), rev : optstr!(card.rev()), role : arystr!(card.role()), sound : arystr!(card.sound()), tel : arystr!(card.tel()), title : arystr!(card.title()), tz : arystr!(card.tz()), uid : optstr!(card.uid()), url : arystr!(card.url()), version : optstr!(card.version()), } } } impl DeserVcard { pub fn adr(&self) -> &Vec { &self.adr } pub fn anniversary(&self) -> Option<&String> { self.anniversary.as_ref() } pub fn bday(&self) -> Option<&String> { self.bday.as_ref() } pub fn categories(&self) -> &Vec { &self.categories } pub fn clientpidmap(&self) -> Option<&String> { self.clientpidmap.as_ref() } pub fn email(&self) -> &Vec { &self.email } pub fn fullname(&self) -> &Vec { &self.fullname } pub fn gender(&self) -> Option<&String> { self.gender.as_ref() } pub fn geo(&self) -> &Vec { &self.geo } pub fn impp(&self) -> &Vec { &self.impp } pub fn key(&self) -> &Vec { &self.key } pub fn lang(&self) -> &Vec { &self.lang } pub fn logo(&self) -> &Vec { &self.logo } pub fn member(&self) -> &Vec { &self.member } pub fn name(&self) -> Option<&String> { self.name.as_ref() } pub fn nickname(&self) -> &Vec { &self.nickname } pub fn note(&self) -> &Vec { &self.note } pub fn org(&self) -> &Vec { &self.org } pub fn photo(&self) -> &Vec { &self.photo } pub fn proid(&self) -> Option<&String> { self.proid.as_ref() } pub fn related(&self) -> &Vec { &self.related } pub fn rev(&self) -> Option<&String> { self.rev.as_ref() } pub fn role(&self) -> &Vec { &self.role } pub fn sound(&self) -> &Vec { &self.sound } pub fn tel(&self) -> &Vec { &self.tel } pub fn title(&self) -> &Vec { &self.title } pub fn tz(&self) -> &Vec { &self.tz } pub fn uid(&self) -> Option<&String> { self.uid.as_ref() } pub fn url(&self) -> &Vec { &self.url } pub fn version(&self) -> Option<&String> { self.version.as_ref() } }