#![deny(
missing_docs,
clippy::all,
clippy::missing_docs_in_private_items,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::cargo
)]
#![warn(clippy::multiple_crate_versions)]
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub mod card;
pub use card::Card;
mod resource;
pub use resource::Resource;
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
pub enum CardVersion {
#[serde(rename = "1.0")]
OneDotZero,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Calendar {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
calendar_type: Option<CalendarType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<CalendarKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum CalendarType {
Calendar,
}
impl Calendar {
pub fn new(uri: &str) -> Self {
Self {
#[cfg(feature = "typed")]
calendar_type: Some(CalendarType::Calendar),
uri: uri.to_string(),
..Resource::default().into()
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum CalendarKind {
Calendar,
FreeBusy,
}
impl From<String> for CalendarKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"calendar" => CalendarKind::Calendar,
"freeBusy" => CalendarKind::FreeBusy,
_ => panic!("Invalid CalendarKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SchedulingAddress {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
scheduling_address_type: Option<SchedulingAddressType>,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum SchedulingAddressType {
SchedulingAddress,
}
impl SchedulingAddress {
pub fn new(uri: &str) -> Self {
Self {
#[cfg(feature = "typed")]
scheduling_address_type: Some(SchedulingAddressType::SchedulingAddress),
uri: uri.to_string(),
contexts: None,
pref: None,
label: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum CardKind {
Application,
Device,
Group,
Individual,
Location,
Org,
}
impl From<String> for CardKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"application" => CardKind::Application,
"device" => CardKind::Device,
"group" => CardKind::Group,
"individual" => CardKind::Individual,
"location" => CardKind::Location,
"org" => CardKind::Org,
_ => panic!("Invalid CardKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct CryptoKey {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
crypto_key_type: Option<CryptoKeyType>,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum CryptoKeyType {
CryptoKey,
}
impl CryptoKey {
pub fn new(uri: &str) -> Self {
Self {
#[cfg(feature = "typed")]
crypto_key_type: Some(CryptoKeyType::CryptoKey),
uri: uri.to_string(),
..Resource::default().into()
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Directory {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
directory_type: Option<DirectoryType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<DirectoryKind>,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub list_as: Option<u64>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum DirectoryType {
Directory,
}
impl Directory {
pub fn new(uri: &str) -> Self {
Self {
#[cfg(feature = "typed")]
directory_type: Some(DirectoryType::Directory),
uri: uri.to_string(),
..Resource::default().into()
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum DirectoryKind {
Directory,
Entry,
}
impl From<String> for DirectoryKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"directory" => DirectoryKind::Directory,
"entry" => DirectoryKind::Entry,
_ => panic!("Invalid DirectoryKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Media {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
media_hidden_type: Option<MediaType>,
pub kind: MediaKind,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum MediaType {
Media,
}
impl Media {
pub fn new(uri: &str, kind: MediaKind) -> Self {
Self {
#[cfg(feature = "typed")]
media_hidden_type: Some(MediaType::Media),
kind,
uri: uri.to_string(),
..Resource::default().into()
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum MediaKind {
#[default]
Photo,
Sound,
Logo,
}
impl From<String> for MediaKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"photo" => MediaKind::Photo,
"sound" => MediaKind::Sound,
"logo" => MediaKind::Logo,
_ => panic!("Invalid MediaKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Link {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
link_type: Option<LinkType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<LinkKind>,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub media_type: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum LinkType {
Link,
}
impl Link {
pub fn new(uri: &str) -> Self {
Self {
#[cfg(feature = "typed")]
link_type: Some(LinkType::Link),
uri: uri.to_string(),
..Resource::default().into()
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum LinkKind {
Contact,
}
impl From<String> for LinkKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"contact" => LinkKind::Contact,
_ => panic!("Invalid LinkKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Relation {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
relation_type: Option<RelationType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub relation: Option<HashMap<RelationshipType, bool>>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(rename_all = "lowercase")]
pub enum RelationshipType {
Acquaintance,
Agent,
Child,
#[serde(rename = "co-resident")]
CoResident,
#[serde(rename = "co-worker")]
CoWorker,
Colleague,
Contact,
Crush,
Date,
Emergency,
Friend,
Kin,
Me,
Met,
Muse,
Neighbor,
Parent,
Sibling,
Spouse,
Sweetheart,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum RelationType {
Relation,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Name {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
name_type: Option<NameType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub components: Option<Vec<NameComponent>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_ordered: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_separator: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub full: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_as: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic_script: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic_system: Option<PhoneticSystem>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum PhoneticSystem {
Ipa,
Jyut,
Piny,
}
impl Default for Name {
fn default() -> Self {
Self {
#[cfg(feature = "typed")]
name_type: Some(NameType::Name),
components: None,
is_ordered: None,
default_separator: None,
full: None,
sort_as: None,
phonetic_script: None,
phonetic_system: None,
}
}
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum NameType {
Name,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct NameComponent {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
name_component_type: Option<NameComponentType>,
pub value: String,
pub kind: NameComponentKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic: Option<String>,
}
impl NameComponent {
pub fn new(kind: NameComponentKind, value: &str) -> Self {
Self {
#[cfg(feature = "typed")]
name_component_type: Some(NameComponentType::NameComponent),
value: value.to_string(),
kind,
phonetic: None,
}
}
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum NameComponentType {
NameComponent,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum NameComponentKind {
Credential,
Generation,
Given,
Given2,
Separator,
Surname,
Surname2,
Title,
}
impl From<String> for NameComponentKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"credential" => NameComponentKind::Credential,
"generation" => NameComponentKind::Generation,
"given" => NameComponentKind::Given,
"given2" => NameComponentKind::Given2,
"separator" => NameComponentKind::Separator,
"surname" => NameComponentKind::Surname,
"surname2" => NameComponentKind::Surname2,
"title" => NameComponentKind::Title,
_ => panic!("Invalid NameComponentKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Nickname {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
nickname_type: Option<NicknameType>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum NicknameType {
Nickname,
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Organization {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
org_type: Option<OrganizationType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub units: Option<Vec<OrgUnit>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_as: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum OrganizationType {
Organization,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct OrgUnit {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
unit_type: Option<OrgUnitType>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub sort_as: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum OrgUnitType {
OrgUnit,
}
impl OrgUnit {
pub fn new(name: &str) -> Self {
Self {
#[cfg(feature = "typed")]
unit_type: Some(OrgUnitType::OrgUnit),
name: name.to_string(),
sort_as: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct SpeakToAs {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
speak_to_as_type: Option<SpeakToAsType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub grammatical_gender: Option<GrammaticalGender>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pronouns: Option<HashMap<String, Pronouns>>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum GrammaticalGender {
Animate,
Common,
Feminine,
Inanimate,
Masculine,
Neuter,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum SpeakToAsType {
SpeakToAs,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Pronouns {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
pronoun_type: Option<PronounsType>,
pub pronouns: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum PronounsType {
Pronouns,
}
impl Pronouns {
pub fn new(pronouns: &str) -> Self {
Self {
#[cfg(feature = "typed")]
pronoun_type: Some(PronounsType::Pronouns),
pronouns: pronouns.to_string(),
contexts: None,
pref: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Title {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
title_type: Option<TitleType>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub kind: Option<TitleKind>,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization_id: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum TitleType {
Title,
}
impl Title {
pub fn new(name: &str) -> Self {
Self {
#[cfg(feature = "typed")]
title_type: Some(TitleType::Title),
name: name.to_string(),
kind: None,
organization_id: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum TitleKind {
Role,
Title,
}
impl From<String> for TitleKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"role" => TitleKind::Role,
"title" => TitleKind::Title,
_ => panic!("Invalid TitleKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct EmailAddress {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
email_type: Option<EmailAddressType>,
pub address: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum EmailAddressType {
EmailAddress,
}
impl EmailAddress {
pub fn new(address: &str) -> Self {
Self {
#[cfg(feature = "typed")]
email_type: Some(EmailAddressType::EmailAddress),
address: address.to_string(),
contexts: None,
pref: None,
label: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct OnlineService {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
service_type: Option<OnlineServiceType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub service: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum OnlineServiceType {
OnlineService,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Phone {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
phone_type: Option<PhoneType>,
pub number: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub features: Option<HashMap<PhoneFeature, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(rename_all = "camelCase")]
pub enum PhoneFeature {
Fax,
#[serde(rename = "main-number")]
MainNumber,
Mobile,
Pager,
Text,
Textphone,
Video,
Voice,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(rename_all = "lowercase")]
pub enum Context {
Private,
Work,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum PhoneType {
Phone,
}
impl Phone {
pub fn new(number: &str) -> Self {
Self {
#[cfg(feature = "typed")]
phone_type: Some(PhoneType::Phone),
number: number.to_string(),
features: None,
contexts: None,
pref: None,
label: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct LanguagePref {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
lang_pref_type: Option<LanguagePrefType>,
pub language: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<Context, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u32>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum LanguagePrefType {
LanguagePref,
}
impl LanguagePref {
pub fn new(language: &str) -> Self {
Self {
#[cfg(feature = "typed")]
lang_pref_type: Some(LanguagePrefType::LanguagePref),
language: language.to_string(),
contexts: None,
pref: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Anniversary {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
anniversary_type: Option<AnniversaryType>,
pub date: DateObject,
pub kind: AnniversaryKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<String, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub place: Option<Address>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum AnniversaryKind {
Birth,
Death,
Wedding,
}
impl From<String> for AnniversaryKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"birth" => AnniversaryKind::Birth,
"death" => AnniversaryKind::Death,
"wedding" => AnniversaryKind::Wedding,
_ => panic!("Invalid AnniversaryKind"),
}
}
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum AnniversaryType {
Anniversary,
}
impl Anniversary {
pub fn new(kind: AnniversaryKind, date: DateObject) -> Self {
Self {
#[cfg(feature = "typed")]
anniversary_type: Some(AnniversaryType::Anniversary),
date,
kind,
contexts: None,
place: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(untagged)]
pub enum DateObject {
Timestamp(Timestamp),
PartialDate(PartialDate),
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Timestamp {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
timestamp_type: Option<TimestampType>,
pub utc: String,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum TimestampType {
Timestamp,
}
impl Timestamp {
pub fn new(utc: &str) -> Self {
Self {
#[cfg(feature = "typed")]
timestamp_type: Some(TimestampType::Timestamp),
utc: utc.to_string(),
}
}
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PartialDate {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
partial_date_type: Option<PartialDateType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub year: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub month: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub day: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub calendar_scale: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum PartialDateType {
PartialDate,
}
#[derive(Serialize, Deserialize, Debug, Default, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Address {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
address_type: Option<AddressType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub components: Option<Vec<AddressComponent>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_ordered: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub country_code: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub coordinates: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub time_zone: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub contexts: Option<HashMap<AddressContext, bool>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub full: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub default_separator: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pref: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic_script: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic_system: Option<PhoneticSystem>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
#[serde(rename_all = "lowercase")]
pub enum AddressContext {
Billing,
Delivery,
Private,
Work,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum AddressType {
Address,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct AddressComponent {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
component_type: Option<AddressComponentType>,
pub value: String,
pub kind: AddressComponentKind,
#[serde(skip_serializing_if = "Option::is_none")]
pub phonetic: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum AddressComponentType {
AddressComponent,
}
impl AddressComponent {
pub fn new(kind: AddressComponentKind, value: &str) -> Self {
Self {
#[cfg(feature = "typed")]
component_type: Some(AddressComponentType::AddressComponent),
value: value.to_string(),
kind,
phonetic: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum AddressComponentKind {
Apartment,
Block,
Building,
Country,
Direction,
District,
Floor,
Landmark,
Locality,
Name,
Number,
Postcode,
#[serde(rename = "postOfficeBox")]
PostOfficeBox,
Region,
Room,
Separator,
Subdistrict,
}
impl From<String> for AddressComponentKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"apartment" => AddressComponentKind::Apartment,
"block" => AddressComponentKind::Block,
"building" => AddressComponentKind::Building,
"country" => AddressComponentKind::Country,
"direction" => AddressComponentKind::Direction,
"district" => AddressComponentKind::District,
"floor" => AddressComponentKind::Floor,
"landmark" => AddressComponentKind::Landmark,
"locality" => AddressComponentKind::Locality,
"name" => AddressComponentKind::Name,
"number" => AddressComponentKind::Number,
"postcode" => AddressComponentKind::Postcode,
"postOfficeBox" => AddressComponentKind::PostOfficeBox,
"region" => AddressComponentKind::Region,
"room" => AddressComponentKind::Room,
"separator" => AddressComponentKind::Separator,
"subdistrict" => AddressComponentKind::Subdistrict,
_ => panic!("Invalid AddressComponentKind"),
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Note {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
note_type: Option<NoteType>,
pub note: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub created: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<Author>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum NoteType {
Note,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Author {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
author_type: Option<AuthorType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub uri: Option<String>,
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum AuthorType {
Author,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub struct PersonalInfo {
#[cfg(feature = "typed")]
#[serde(skip_serializing_if = "Option::is_none")]
#[serde(rename = "@type")]
personal_info_type: Option<PersonalInfoType>,
pub kind: PersonalInfoKind,
pub value: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub level: Option<PersonalInfoLevel>,
#[serde(skip_serializing_if = "Option::is_none")]
pub list_as: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum PersonalInfoKind {
Expertise,
Hobby,
Interest,
}
impl From<String> for PersonalInfoKind {
fn from(kind: String) -> Self {
match kind.as_str() {
"expertise" => PersonalInfoKind::Expertise,
"hobby" => PersonalInfoKind::Hobby,
"interest" => PersonalInfoKind::Interest,
_ => panic!("Invalid PersonalInfoKind"),
}
}
}
#[cfg(feature = "typed")]
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
enum PersonalInfoType {
PersonalInfo,
}
impl PersonalInfo {
pub fn new(kind: PersonalInfoKind, value: &str) -> Self {
Self {
#[cfg(feature = "typed")]
personal_info_type: Some(PersonalInfoType::PersonalInfo),
kind,
value: value.to_string(),
level: None,
list_as: None,
label: None,
}
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
#[serde(rename_all = "camelCase")]
pub enum PersonalInfoLevel {
High,
Medium,
Low,
}