summaryrefslogtreecommitdiff
path: root/src/viewmodel
diff options
context:
space:
mode:
Diffstat (limited to 'src/viewmodel')
-rw-r--r--src/viewmodel/address.rs113
-rw-r--r--src/viewmodel/dates.rs45
-rw-r--r--src/viewmodel/mod.rs231
-rw-r--r--src/viewmodel/name.rs119
-rw-r--r--src/viewmodel/organizational.rs88
-rw-r--r--src/viewmodel/telephone.rs106
-rw-r--r--src/viewmodel/utility.rs45
-rw-r--r--src/viewmodel/vcard.rs40
8 files changed, 0 insertions, 787 deletions
diff --git a/src/viewmodel/address.rs b/src/viewmodel/address.rs
deleted file mode 100644
index 9542675..0000000
--- a/src/viewmodel/address.rs
+++ /dev/null
@@ -1,113 +0,0 @@
-use super::*;
-use crate::view::address::*;
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct Address {
- pub post_office_box: String,
- pub extension: String,
- pub street: String,
- pub locality: String,
- pub region: String,
- pub code: String,
- pub country: String,
- pub work: bool,
- pub home: bool,
-}
-
-impl VCardPropertyInputObject<AddressView> for Address {
- fn new() -> Self {
- Self {
- post_office_box: String::new(),
- extension: String::new(),
- street: String::new(),
- locality: String::new(),
- region: String::new(),
- code: String::new(),
- country: String::new(),
- work: false,
- home: false,
- }
- }
- fn get_input_fields(&self, link: &ComponentLink<AddressView>) -> Vec<VCardPropertyInputField> {
- let typ = String::from("text");
- vec![
- VCardPropertyInputField::Text {
- label: "Post Office Box".to_string(),
- id: Some("post_office_box".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdatePostOfficeBox(e.value)),
- value: self.post_office_box.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Extension".to_string(),
- id: Some("extension".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateExtension(e.value)),
- value: self.extension.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Street".to_string(),
- id: Some("street".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateStreet(e.value)),
- value: self.street.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Locality".to_string(),
- id: Some("locality".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateLocality(e.value)),
- value: self.locality.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Region".to_string(),
- id: Some("region".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateRegion(e.value)),
- value: self.region.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Code".to_string(),
- id: Some("code".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateCode(e.value)),
- value: self.code.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Country".to_string(),
- id: Some("country".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateCountry(e.value)),
- value: self.country.clone(),
- typ,
- },
- VCardPropertyInputField::CheckBox {
- label: "Work".to_string(),
- id: Some("work".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleWork),
- value: self.work,
- },
- VCardPropertyInputField::CheckBox {
- label: "Home".to_string(),
- id: Some("home".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleHome),
- value: self.home,
- },
- ]
- }
- fn is_empty(&self) -> bool {
- self.post_office_box.is_empty()
- && self.extension.is_empty()
- && self.street.is_empty()
- && self.locality.is_empty()
- && self.region.is_empty()
- && self.code.is_empty()
- && self.country.is_empty()
- }
-}
diff --git a/src/viewmodel/dates.rs b/src/viewmodel/dates.rs
deleted file mode 100644
index 7d8d394..0000000
--- a/src/viewmodel/dates.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-use super::*;
-use crate::view::dates::*;
-
-/// Type that represents the vcard `anniversary` and `birthday` properties.
-#[derive(Clone, Debug, PartialEq)]
-pub struct Dates {
- pub anniversary: String,
- pub birthday: String,
-}
-
-impl VCardPropertyInputObject<DatesView> for Dates {
- fn new() -> Self {
- Self {
- anniversary: String::new(),
- birthday: String::new(),
- }
- }
- fn get_input_fields(
- &self,
- link: &yew::html::Scope<DatesView>,
- ) -> std::vec::Vec<VCardPropertyInputField> {
- let typ = String::from("date");
- vec![
- VCardPropertyInputField::Text {
- label: "Anniversary".to_string(),
- id: Some("anniversary".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateAnniversary(e.value)),
- value: self.anniversary.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Birthday".to_string(),
- id: Some("birthday".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateBirthday(e.value)),
- value: self.birthday.clone(),
- typ,
- },
- ]
- }
- fn is_empty(&self) -> bool {
- self.anniversary.is_empty() && self.birthday.is_empty()
- }
-}
diff --git a/src/viewmodel/mod.rs b/src/viewmodel/mod.rs
deleted file mode 100644
index 0385c61..0000000
--- a/src/viewmodel/mod.rs
+++ /dev/null
@@ -1,231 +0,0 @@
-use crate::view::VCardPropertyInputComponent;
-use crate::viewmodel::utility::File;
-use wasm_bindgen::closure::Closure;
-use wasm_bindgen::JsCast;
-use web_sys::FileReader;
-use yew::prelude::*;
-use yew::services::ConsoleService;
-
-pub mod address;
-pub mod dates;
-pub mod name;
-pub mod organizational;
-pub mod telephone;
-pub mod utility;
-pub mod vcard;
-
-/// Trait for types that represent the data of a vcard property used inside of a `VCardPropertyInputComponent`.
-pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>>:
- Clone + PartialEq
-where
- Self: Sized,
-{
- /// Function for creating a new (and empty) `VCardPropertyInputObject`.
- fn new() -> Self;
- /// Converts each field of the `VCardPropertyInputObject` to a VCardPropertyInputField and returns them as a vector.
- fn get_input_fields(&self, link: &ComponentLink<C>) -> Vec<VCardPropertyInputField>;
- /// Returns a `Html` representation of the `VCardPropertyInputObject`.
- fn render(&self, link: &ComponentLink<C>) -> Html {
- html! {
- <div class="columns is-mobile is-multiline">
- {
- for self.get_input_fields(link).iter().map(|field|
- field.render()
- )
- }
- </div>
- }
- }
- /// Convenience function for checking if the `VCardPropertyInputObject` is empty.
- fn is_empty(&self) -> bool;
-}
-
-/// Type for saving error messages.
-///
-/// More of a placeholder for something better later on.
-#[derive(Debug, Clone, PartialEq)]
-pub struct Error {
- pub msg: String,
-}
-
-/// Type that represents the visiual appearance of an input field.
-pub enum VCardPropertyInputField {
- Text {
- label: String,
- id: Option<String>,
- placeholder: Option<String>,
- oninput: Callback<InputData>,
- value: String,
- typ: String,
- },
- File {
- label: String,
- name: String,
- callback: Callback<Option<File>>,
- value: Option<File>,
- },
- CheckBox {
- label: String,
- id: Option<String>,
- onclick: Callback<MouseEvent>,
- value: bool,
- },
-}
-
-impl VCardPropertyInputField {
- /// Returns a `Html` representation of the `VCardPropertyInputField`.
- pub fn render(&self) -> Html {
- match self {
- Self::Text {
- label,
- id,
- placeholder,
- oninput,
- value: _,
- typ,
- } => Self::text_field_input(label, id, placeholder, oninput, typ),
- Self::File {
- label,
- name,
- callback,
- value,
- } => Self::file_field_input(label, name, callback, value),
- Self::CheckBox {
- label,
- id,
- onclick,
- value,
- } => Self::checkbox_field_input(label, id, value, onclick),
- }
- }
- /// Returns an `Html` representation of a text input field with the given parameters.
- fn text_field_input(
- label: &str,
- id: &Option<String>,
- placeholder: &Option<String>,
- oninput: &Callback<InputData>,
- typ: &str,
- ) -> Html {
- html! {
- <div class="field column
- is-one-fifth-widescreen
- is-one-quarter-desktop
- is-one-third-tablet
- is-half-mobile" >
- <label class="label">{ label }</label>
- <div class="control">
- <input id=id.as_ref().unwrap_or(&"".to_string())
- type=typ
- placeholder=placeholder.as_ref().unwrap_or(&"".to_string())
- oninput=oninput
- />
- </div>
- </div>
- }
- }
- /// Returns an `Html` representation of a file input field with the given parameters.
- fn file_field_input(
- label: &str,
- name: &str,
- callback: &Callback<Option<File>>,
- file: &Option<File>,
- ) -> Html {
- let callback = callback.clone();
- let onchange = Callback::<()>::default();
- let onchange = onchange.reform(move |c: ChangeData| {
- if let ChangeData::Files(files) = c {
- match files.item(0) {
- Some(file) => {
- let file_reader = FileReader::new().unwrap();
- match file_reader.read_as_data_url(&file) {
- Ok(_) => (),
- Err(_) => ConsoleService::warn("Error: Couldn't get file as data url."),
- };
-
- let callback = callback.clone();
- let onload = Closure::wrap(Box::new(move |event: Event| {
- let file_reader: FileReader =
- event.target().unwrap().dyn_into().unwrap();
- let data_url: Option<String> =
- file_reader.result().unwrap().as_string();
- match data_url {
- Some(content) => callback.emit(Some(File {
- name: file.name(),
- content,
- })),
- None => {
- ConsoleService::warn("Couldn't get data url as string.");
- callback.emit(None);
- }
- };
- }) as Box<dyn FnMut(_)>);
-
- file_reader.set_onload(Some(onload.as_ref().unchecked_ref()));
- onload.forget();
- }
- None => callback.emit(None),
- }
- } else {
- callback.emit(None);
- }
- });
- html! {
- <div class="field column
- is-one-fifth-widescreen
- is-one-quarter-desktop
- is-one-third-tablet
- is-half-mobile" >
- <label class="label">{ label }</label>
- <div class="file has-name control">
- <label class="file-label">
- <input class="file-input"
- type="file"
- name=name
- onchange=onchange
- />
- <span class="file-cta">
- <span class="file-icon">
- <i class="fas fa-upload"></i>
- </span>
- <span class="file-label">
- { "Choose file..." }
- </span>
- </span>
- <span class="file-name">
- {
- match file {
- Some(file) => file.name.clone(),
- None => String::from("No file selected"),
- }
- }
- </span>
- </label>
- </div>
- </div>
- }
- }
- /// Returns an `Html` representation of a checkbox input field with the given parameters.
- fn checkbox_field_input(
- label: &str,
- id: &Option<String>,
- checked: &bool,
- onclick: &Callback<MouseEvent>,
- ) -> Html {
- html! {
- <div class="field column
- is-one-fifth-widescreen
- is-one-quarter-desktop
- is-one-third-tablet
- is-half-mobile" >
- <label class="checkbox">
- <input id=id.as_ref().unwrap_or(&"".to_string())
- type="checkbox"
- checked=*checked
- onclick=onclick
- />
- { label }
- </label>
- </div>
- }
- }
-}
diff --git a/src/viewmodel/name.rs b/src/viewmodel/name.rs
deleted file mode 100644
index de0aa81..0000000
--- a/src/viewmodel/name.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-use super::*;
-use crate::view::name::*;
-
-/// Type that represents a vcard `name` property
-///
-/// # Examples
-/// ```
-/// # use bcard_wasm_webapp::viewmodel::name::Name;
-/// # use crate::bcard_wasm_webapp::viewmodel::VCardPropertyInputObject;
-/// let mut name = Name::new();
-/// name.prefix = String::from("Sir");
-/// name.first_name = String::from("Arthur");
-/// name.middle_name = String::from("Charles");
-/// name.last_name = String::from("Clarke");
-/// name.suffix = String::from("CBE FRAS");
-///
-/// assert_eq!(name.generate_fn(), String::from("Sir Arthur Charles Clarke, CBE FRAS"));
-/// ```
-#[derive(Clone, Debug, PartialEq)]
-pub struct Name {
- pub prefix: String,
- pub first_name: String,
- pub middle_name: String,
- pub last_name: String,
- pub suffix: String,
-}
-
-impl VCardPropertyInputObject<NameView> for Name {
- fn new() -> Self {
- Self {
- prefix: String::new(),
- first_name: String::new(),
- middle_name: String::new(),
- last_name: String::new(),
- suffix: String::new(),
- }
- }
- fn get_input_fields(
- &self,
- link: &ComponentLink<NameView>,
- ) -> std::vec::Vec<VCardPropertyInputField> {
- let typ = String::from("text");
- vec![
- VCardPropertyInputField::Text {
- label: "Prefix".to_string(),
- id: Some("prefix".to_string()),
- placeholder: Some("Sir".to_string()),
- oninput: link.callback(|e: InputData| Msg::UpdatePrefix(e.value)),
- value: self.prefix.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "First Name".to_string(),
- id: Some("first_name".to_string()),
- placeholder: Some("Arthur".to_string()),
- oninput: link.callback(|e: InputData| Msg::UpdateFirstName(e.value)),
- value: self.first_name.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Middle Name".to_string(),
- id: Some("middle_name".to_string()),
- placeholder: Some("Charles".to_string()),
- oninput: link.callback(|e: InputData| Msg::UpdateMiddleName(e.value)),
- value: self.middle_name.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Last Name".to_string(),
- id: Some("last_name".to_string()),
- placeholder: Some("Clarke".to_string()),
- oninput: link.callback(|e: InputData| Msg::UpdateLastName(e.value)),
- value: self.last_name.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Suffix".to_string(),
- id: Some("suffix".to_string()),
- placeholder: Some("CBE FRAS".to_string()),
- oninput: link.callback(|e: InputData| Msg::UpdateSuffix(e.value)),
- value: self.suffix.clone(),
- typ,
- },
- ]
- }
- fn is_empty(&self) -> bool {
- self.prefix.is_empty()
- && self.first_name.is_empty()
- && self.middle_name.is_empty()
- && self.last_name.is_empty()
- && self.suffix.is_empty()
- }
-}
-
-impl Name {
- pub fn generate_fn(&self) -> String {
- let mut full_name = String::new();
-
- full_name.push_str(&self.prefix);
- if !self.first_name.is_empty() {
- full_name.push_str(" ");
- full_name.push_str(&self.first_name);
- }
- if !self.middle_name.is_empty() {
- full_name.push_str(" ");
- full_name.push_str(&self.middle_name);
- }
- if !self.last_name.is_empty() {
- full_name.push_str(" ");
- full_name.push_str(&self.last_name);
- }
- if !self.suffix.is_empty() {
- full_name.push_str(", ");
- full_name.push_str(&self.suffix);
- }
-
- full_name
- }
-}
diff --git a/src/viewmodel/organizational.rs b/src/viewmodel/organizational.rs
deleted file mode 100644
index 72b19d2..0000000
--- a/src/viewmodel/organizational.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-use super::*;
-use crate::view::organizational::*;
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct Organizational {
- pub org: String,
- pub logo: Option<File>,
- pub title: String,
- pub role: String,
- pub member: String,
- pub related: String,
-}
-
-impl VCardPropertyInputObject<OrganizationalView> for Organizational {
- fn new() -> Self {
- Self {
- org: String::new(),
- logo: None,
- title: String::new(),
- role: String::new(),
- member: String::new(),
- related: String::new(),
- }
- }
- fn get_input_fields(
- &self,
- link: &yew::html::Scope<OrganizationalView>,
- ) -> std::vec::Vec<VCardPropertyInputField> {
- let typ = String::from("text");
- vec![
- VCardPropertyInputField::Text {
- label: "Organisation".to_string(),
- id: Some("org".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateOrg(e.value)),
- value: self.org.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::File {
- // TODO: Add Upload for logo
- label: "Logo".to_string(),
- name: "logo".to_string(),
- callback: link.callback(|file: Option<File>| Msg::UpdateLogo(file)),
- value: self.logo.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Title".to_string(),
- id: Some("title".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateTitle(e.value)),
- value: self.title.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Role".to_string(),
- id: Some("role".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateRole(e.value)),
- value: self.role.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Member".to_string(),
- id: Some("member".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateMember(e.value)),
- value: self.member.clone(),
- typ: typ.clone(),
- },
- VCardPropertyInputField::Text {
- label: "Related".to_string(),
- id: Some("related".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateRelated(e.value)),
- value: self.related.clone(),
- typ: typ,
- },
- ]
- }
- fn is_empty(&self) -> bool {
- self.org.is_empty()
- && self.logo.is_none()
- && self.title.is_empty()
- && self.role.is_empty()
- && self.member.is_empty()
- && self.related.is_empty()
- }
-}
diff --git a/src/viewmodel/telephone.rs b/src/viewmodel/telephone.rs
deleted file mode 100644
index 44b938f..0000000
--- a/src/viewmodel/telephone.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-use super::*;
-use crate::view::telephone::*;
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct Telephone {
- pub number: String,
- pub work: bool,
- pub home: bool,
- pub text: bool,
- pub voice: bool,
- pub fax: bool,
- pub cell: bool,
- pub video: bool,
- pub pager: bool,
- pub text_phone: bool,
-}
-
-impl VCardPropertyInputObject<TelephoneView> for Telephone {
- fn new() -> Self {
- Self {
- number: String::new(),
- work: false,
- home: false,
- text: false,
- voice: false,
- fax: false,
- cell: false,
- video: false,
- pager: false,
- text_phone: false,
- }
- }
- fn get_input_fields(
- &self,
- link: &ComponentLink<TelephoneView>,
- ) -> Vec<VCardPropertyInputField> {
- let typ = String::from("tel");
- vec![
- VCardPropertyInputField::Text {
- label: "Number".to_string(),
- id: Some("number".to_string()),
- placeholder: None,
- oninput: link.callback(|e: InputData| Msg::UpdateNumber(e.value)),
- value: self.number.clone(),
- typ,
- },
- VCardPropertyInputField::CheckBox {
- label: "Work".to_string(),
- id: Some("work".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleWork),
- value: self.work,
- },
- VCardPropertyInputField::CheckBox {
- label: "Home".to_string(),
- id: Some("home".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleHome),
- value: self.home,
- },
- VCardPropertyInputField::CheckBox {
- label: "Text".to_string(),
- id: Some("text".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleText),
- value: self.text,
- },
- VCardPropertyInputField::CheckBox {
- label: "Voice".to_string(),
- id: Some("voice".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleVoice),
- value: self.voice,
- },
- VCardPropertyInputField::CheckBox {
- label: "Fax".to_string(),
- id: Some("fax".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleFax),
- value: self.fax,
- },
- VCardPropertyInputField::CheckBox {
- label: "Cell".to_string(),
- id: Some("cell".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleCell),
- value: self.cell,
- },
- VCardPropertyInputField::CheckBox {
- label: "Video".to_string(),
- id: Some("video".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleVideo),
- value: self.video,
- },
- VCardPropertyInputField::CheckBox {
- label: "Pager".to_string(),
- id: Some("pager".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::TogglePager),
- value: self.pager,
- },
- VCardPropertyInputField::CheckBox {
- label: "Text Phone".to_string(),
- id: Some("text_phone".to_string()),
- onclick: link.callback(|_: MouseEvent| Msg::ToggleTextPhone),
- value: self.text_phone,
- },
- ]
- }
- fn is_empty(&self) -> bool {
- self.number.is_empty()
- }
-}
diff --git a/src/viewmodel/utility.rs b/src/viewmodel/utility.rs
deleted file mode 100644
index 617ee45..0000000
--- a/src/viewmodel/utility.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-#[derive(Clone)]
-pub struct Download {
- pub file_name: String,
- pub content: String,
- pub mime_type: MimeType,
-}
-
-impl Download {
- pub fn as_data_link(&self) -> String {
- let data = base64::encode(&*self.content);
- let uri_component: String = js_sys::encode_uri_component(&data).into();
-
- format!("data:{};base64,{}", self.mime_type.as_text(), uri_component)
- }
-}
-
-#[derive(Clone, Copy)]
-pub enum MimeType {
- PDF,
- VCard,
- SVG,
-}
-
-impl MimeType {
- pub fn as_text(&self) -> &str {
- match self {
- MimeType::PDF => "application/pdf",
- MimeType::VCard => "text/vcard",
- MimeType::SVG => "image/svg+xml",
- }
- }
-}
-
-#[derive(Clone, Copy, PartialEq)]
-pub enum DownloadOption {
- PDF,
- VCard,
- QrCode,
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct File {
- pub name: String,
- pub content: String,
-}
diff --git a/src/viewmodel/vcard.rs b/src/viewmodel/vcard.rs
deleted file mode 100644
index 18ce43a..0000000
--- a/src/viewmodel/vcard.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-use crate::viewmodel::address::Address;
-use crate::viewmodel::dates::Dates;
-use crate::viewmodel::name::Name;
-use crate::viewmodel::organizational::Organizational;
-use crate::viewmodel::telephone::Telephone;
-
-/// Type that represents the data structure of a vcard.
-#[derive(Clone, Debug)]
-pub struct VCardData {
- pub names: Vec<Name>,
- pub addresses: Vec<Address>,
- pub telephones: Vec<Telephone>,
- pub datess: Vec<Dates>,
- pub organizationals: Vec<Organizational>,
-}
-
-macro_rules! make_vec_adder_fn {
- ( fn $fnname:ident $property:ident => $($arg_name:ident : $arg_type:ty),* ) => {
- pub fn $fnname(&mut self, $( $arg_name : $arg_type ),*) {
- $(self.$property.push($arg_name);)*
- }
- };
-}
-
-impl VCardData {
- pub fn new() -> Self {
- Self {
- names: Vec::new(),
- addresses: Vec::new(),
- telephones: Vec::new(),
- datess: Vec::new(),
- organizationals: Vec::new(),
- }
- }
- make_vec_adder_fn!( fn add_name names => name: Name );
- make_vec_adder_fn!( fn add_address addresses => address: Address );
- make_vec_adder_fn!( fn add_telephone telephones => telephone: Telephone );
- make_vec_adder_fn!( fn add_dates datess => dates: Dates );
- make_vec_adder_fn!( fn add_organizational organizationals => organizational: Organizational );
-}