diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 10 | ||||
| -rw-r--r-- | src/view/address.rs | 28 | ||||
| -rw-r--r-- | src/view/dates.rs | 18 | ||||
| -rw-r--r-- | src/view/main.rs | 345 | ||||
| -rw-r--r-- | src/view/mod.rs | 25 | ||||
| -rw-r--r-- | src/view/name.rs | 28 | ||||
| -rw-r--r-- | src/view/organizational.rs | 20 | ||||
| -rw-r--r-- | src/view/telephone.rs | 26 | ||||
| -rw-r--r-- | src/viewmodel/address.rs | 36 | ||||
| -rw-r--r-- | src/viewmodel/dates.rs | 16 | ||||
| -rw-r--r-- | src/viewmodel/mod.rs | 103 | ||||
| -rw-r--r-- | src/viewmodel/name.rs | 31 | ||||
| -rw-r--r-- | src/viewmodel/organizational.rs | 71 | ||||
| -rw-r--r-- | src/viewmodel/telephone.rs | 27 | ||||
| -rw-r--r-- | src/viewmodel/utility.rs | 6 | ||||
| -rw-r--r-- | src/viewmodel/vcard.rs | 8 | 
16 files changed, 391 insertions, 407 deletions
@@ -1,10 +1,10 @@ -#![recursion_limit="1024"] -extern crate wee_alloc; +#![recursion_limit = "1024"]  extern crate console_error_panic_hook; -use wasm_bindgen::prelude::*; -use yew::prelude::App; +extern crate wee_alloc;  use std::panic;  use view::main::MainView; +use wasm_bindgen::prelude::*; +use yew::prelude::App;  // Use `wee_alloc` as the global allocator.  #[global_allocator] @@ -21,4 +21,4 @@ fn init() {  pub fn run_app() {      init();      App::<MainView>::new().mount_to_body(); -}
\ No newline at end of file +} diff --git a/src/view/address.rs b/src/view/address.rs index a945272..57ea7e4 100644 --- a/src/view/address.rs +++ b/src/view/address.rs @@ -1,28 +1,28 @@ +use super::VCardPropertyInputComponent;  use crate::view::InputProps; -use yew::prelude::*; -use yewtil::NeqAssign;  use crate::viewmodel::address::*; -use crate::viewmodel::VCardPropertyInputObject; -use super::VCardPropertyInputComponent;  use crate::viewmodel::Error; +use crate::viewmodel::VCardPropertyInputObject; +use yew::prelude::*; +use yewtil::NeqAssign; -type Props = InputProps<Address,AddressView>; +type Props = InputProps<Address, AddressView>;  /// View Component for a `address` field -///  +///  /// # Examples -///  +///  /// ```compile_fail  /// let html = html!{ -///     <AddressView    weak_link=some_weak_component_link  +///     <AddressView    weak_link=some_weak_component_link  ///                     generated=self.link.callback( -///                         |n: Irc<Address>|  +///                         |n: Irc<Address>|  ///                         Msg::GeneratedAddress(some_address)  ///                     )  ///     />  /// };  /// ``` -#[derive(Clone,PartialEq)] +#[derive(Clone, PartialEq)]  pub struct AddressView {      props: Props,      value: Address, @@ -79,17 +79,17 @@ impl Component for AddressView {              Msg::ToggleHome => self.value.home = !self.value.home,              Msg::Generate => {                  self.props.generated.emit(self.value.clone()); -            }, +            }          };          true      } -    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {  +    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {          self.props.neq_assign(props)      }      fn view(&self) -> yew::virtual_dom::VNode {          let link = self.props.weak_link.borrow().clone().unwrap(); -        html!{ +        html! {              <div class="box">                  { self.render_error() } @@ -100,4 +100,4 @@ impl Component for AddressView {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/view/dates.rs b/src/view/dates.rs index de3d311..b2a6dd3 100644 --- a/src/view/dates.rs +++ b/src/view/dates.rs @@ -1,14 +1,14 @@ +use super::VCardPropertyInputComponent;  use crate::view::InputProps; -use yew::prelude::*; -use yewtil::NeqAssign; -use crate::viewmodel::Error;  use crate::viewmodel::dates::*; +use crate::viewmodel::Error;  use crate::viewmodel::VCardPropertyInputObject; -use super::VCardPropertyInputComponent; +use yew::prelude::*; +use yewtil::NeqAssign; -type Props = InputProps<Dates,DatesView>; +type Props = InputProps<Dates, DatesView>; -#[derive(Clone,PartialEq)] +#[derive(Clone, PartialEq)]  pub struct DatesView {      props: Props,      value: Dates, @@ -51,7 +51,7 @@ impl Component for DatesView {              Msg::UpdateBirthday(b) => self.value.birthday = b,              Msg::Generate => {                  self.props.generated.emit(self.value.clone()); -            }, +            }          };          true      } @@ -61,7 +61,7 @@ impl Component for DatesView {      fn view(&self) -> yew::virtual_dom::VNode {          let link = self.props.weak_link.borrow().clone().unwrap(); -        html!{ +        html! {              <div class="box">                  { self.render_error() } @@ -72,4 +72,4 @@ impl Component for DatesView {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/view/main.rs b/src/view/main.rs index d6b2cb9..196afa0 100644 --- a/src/view/main.rs +++ b/src/view/main.rs @@ -1,30 +1,29 @@ -use crate::viewmodel::organizational::Organizational; -use crate::view::organizational::{self,OrganizationalView}; +use super::address::{self, AddressView}; +use super::dates::{self, DatesView}; +use super::name::{self, NameView}; +use super::WeakComponentLink; +use crate::view::organizational::{self, OrganizationalView}; +use crate::view::telephone::{self, TelephoneView}; +use crate::viewmodel::address::Address;  use crate::viewmodel::dates::Dates; -use yew::services::ConsoleService; +use crate::viewmodel::name::Name; +use crate::viewmodel::organizational::Organizational; +use crate::viewmodel::telephone::Telephone; +use crate::viewmodel::utility::*;  use crate::viewmodel::vcard::VCardData;  use crate::viewmodel::Error; -use crate::view::telephone::{self,TelephoneView};  use crate::viewmodel::VCardPropertyInputObject; -use super::WeakComponentLink; -use super::name::{self,NameView}; -use super::address::{self,AddressView}; -use super::dates::{self,DatesView}; +use boolinator::Boolinator; +use chrono::prelude::*;  use genpdf::Element as _; -use genpdf::{elements, style, fonts}; +use genpdf::{elements, fonts, style};  use qrcodegen::QrCode;  use qrcodegen::QrCodeEcc; +use vobject::parameters; +use vobject::vcard::VcardBuilder;  use yew::prelude::*; +use yew::services::ConsoleService;  use yewtil::ptr::Mrc; -use vobject::vcard::VcardBuilder; -use vobject::parameters; -use chrono::prelude::*; -use crate::viewmodel::name::Name; -use crate::viewmodel::address::Address; -use crate::viewmodel::telephone::Telephone; -use crate::viewmodel::utility::*; -use boolinator::Boolinator; -  pub struct MainView {      link: ComponentLink<Self>, @@ -67,10 +66,10 @@ impl Component for MainView {      type Properties = ();      fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self { -        MainView {  -            link,  -            error: None,  -            download: None,  +        MainView { +            link, +            error: None, +            download: None,              selected_option: DownloadOption::VCard,              vcard_data: Mrc::new(VCardData::new()), @@ -91,31 +90,31 @@ impl Component for MainView {              Msg::AddName => {                  self.name_links.push(WeakComponentLink::default());                  shouldrender = true; -            }, +            }              Msg::AddAddress => {                  self.address_links.push(WeakComponentLink::default());                  shouldrender = true; -            }, +            }              Msg::AddTelephone => {                  self.telephone_links.push(WeakComponentLink::default());                  shouldrender = true; -            }, +            }              Msg::AddDates => {                  self.dates_links.push(WeakComponentLink::default());                  shouldrender = true; -            }, +            }              Msg::AddOrganizational => {                  self.organizational_links.push(WeakComponentLink::default());                  shouldrender = true; -            }, +            }              Msg::ChangeDownloadOption(option) => {                  self.selected_option = option;                  shouldrender = false; -            }, +            }              Msg::Generate => { - -                if self.selected_option == DownloadOption::VCard || self.selected_option == DownloadOption::QrCode { - +                if self.selected_option == DownloadOption::VCard +                    || self.selected_option == DownloadOption::QrCode +                {                      for name_link in self.name_links.iter() {                          let name_link = name_link.borrow().clone().unwrap();                          name_link.send_message(name::Msg::Generate); @@ -158,52 +157,55 @@ impl Component for MainView {                  */                  shouldrender = true; -            }, +            }              Msg::GeneratedName(name) => { -                  self.answer_count += 1;                  match self.vcard_data.get_mut() {                      Some(vcard_data) => vcard_data.add_name(name), -                    None => ConsoleService::info("Error in GeneratedName: Couldn't get mutable borrow of VCardData"), +                    None => ConsoleService::info( +                        "Error in GeneratedName: Couldn't get mutable borrow of VCardData", +                    ),                  };                  shouldrender = true; - -            }, +            }              Msg::GeneratedAddress(address) => { -                  self.answer_count += 1;                  match self.vcard_data.get_mut() {                      Some(vcard_data) => vcard_data.add_address(address), -                    None => ConsoleService::info("Error in GeneratedAddress: Couldn't get mutable borrow of VCardData"), +                    None => ConsoleService::info( +                        "Error in GeneratedAddress: Couldn't get mutable borrow of VCardData", +                    ),                  }; -                 +                  shouldrender = true; -            }, +            }              Msg::GeneratedTelephone(telephone) => { -                  self.answer_count += 1;                  match self.vcard_data.get_mut() {                      Some(vcard_data) => vcard_data.add_telephone(telephone), -                    None => ConsoleService::info("Error in GeneratedTelephone: Couldn't get mutable borrow of VCardData"), +                    None => ConsoleService::info( +                        "Error in GeneratedTelephone: Couldn't get mutable borrow of VCardData", +                    ),                  };                  shouldrender = true; -            }, +            }              Msg::GeneratedDates(dates) => { -                  self.answer_count += 1;                  match self.vcard_data.get_mut() {                      Some(vcard_data) => vcard_data.add_dates(dates), -                    None => ConsoleService::info("Error in GeneratedDates: Couldn't get mutable borrow of VCardData"), +                    None => ConsoleService::info( +                        "Error in GeneratedDates: Couldn't get mutable borrow of VCardData", +                    ),                  };                  shouldrender = true; -            }, +            }              Msg::GeneratedOrganizational(organizational) => {                  self.answer_count += 1; @@ -213,9 +215,8 @@ impl Component for MainView {                  };                  shouldrender = true; -            }, +            }              Msg::GenerationComplete => { -                  self.answer_count = 0;                  let vcard_data = self.vcard_data.clone_inner(); @@ -223,33 +224,20 @@ impl Component for MainView {                  let mut builder = VcardBuilder::new();                  for name in vcard_data.names { -                      if !name.is_empty() { - -                        builder = builder -                        .with_fullname( -                            name.generate_fn() -                        ) -                        .with_name( +                        builder = builder.with_fullname(name.generate_fn()).with_name(                              parameters!(), -                            (!name.last_name.is_empty()) -                                .as_some(name.last_name.clone()), -                            (!name.first_name.is_empty()) -                                .as_some(name.first_name.clone()), -                            (!name.middle_name.is_empty()) -                                .as_some(name.middle_name.clone()), -                            (!name.prefix.is_empty()) -                                .as_some(name.prefix.clone()), -                            (!name.suffix.is_empty()) -                                .as_some(name.suffix.clone()) +                            (!name.last_name.is_empty()).as_some(name.last_name.clone()), +                            (!name.first_name.is_empty()).as_some(name.first_name.clone()), +                            (!name.middle_name.is_empty()).as_some(name.middle_name.clone()), +                            (!name.prefix.is_empty()).as_some(name.prefix.clone()), +                            (!name.suffix.is_empty()).as_some(name.suffix.clone()),                          );                      }                  }                  for address in vcard_data.addresses { -                      if !address.is_empty() { -                          let mut types = String::new();                          if address.work {                              types.push_str("WORK"); @@ -260,37 +248,29 @@ impl Component for MainView {                              }                              types.push_str("HOME")                          } -     +                          let params = if types.is_empty() {                              parameters!()                          } else {                              parameters!("TYPE" => types)                          }; -     +                          builder = builder.with_adr(                              params,                              (!address.post_office_box.is_empty())                                  .as_some(address.post_office_box.clone()), -                            (!address.extension.is_empty()) -                                .as_some(address.extension.clone()), -                            (!address.street.is_empty()) -                                .as_some(address.street.clone()), -                            (!address.locality.is_empty()) -                                .as_some(address.locality.clone()), -                            (!address.region.is_empty()) -                                .as_some(address.region.clone()), -                            (!address.code.is_empty()) -                                .as_some(address.code.clone()), -                            (!address.country.is_empty()) -                                .as_some(address.country.clone()), +                            (!address.extension.is_empty()).as_some(address.extension.clone()), +                            (!address.street.is_empty()).as_some(address.street.clone()), +                            (!address.locality.is_empty()).as_some(address.locality.clone()), +                            (!address.region.is_empty()).as_some(address.region.clone()), +                            (!address.code.is_empty()).as_some(address.code.clone()), +                            (!address.country.is_empty()).as_some(address.country.clone()),                          );                      }                  }                  for telephone in vcard_data.telephones { -                      if !telephone.is_empty() { -                                                  let mut types = String::new();                          if telephone.work {                              types.push_str("WORK"); @@ -343,36 +323,28 @@ impl Component for MainView {                              }                              types.push_str("TEXTPHONE")                          } -     +                          let params = if types.is_empty() {                              parameters!()                          } else {                              parameters!("TYPE" => types)                          }; -     -                        builder = builder.with_tel( -                            params, -                            telephone.number.clone(), -                        ); + +                        builder = builder.with_tel(params, telephone.number.clone());                      }                  }                  for dates in vcard_data.datess { -                      if !dates.anniversary.is_empty() {                          builder = builder.with_anniversary(dates.anniversary);                      }                      if !dates.birthday.is_empty() { -                        builder = builder.with_bday( -                            parameters!(), -                            dates.birthday -                        ); +                        builder = builder.with_bday(parameters!(), dates.birthday);                      }                  }                  for organizational in vcard_data.organizationals { -                      if !organizational.org.is_empty() {                          builder = builder.with_org(vec![organizational.org]);                      } @@ -398,50 +370,51 @@ impl Component for MainView {                          builder = builder.with_related(organizational.related);                      }                  } -                                      let rev = Local::now(); -                 +                  match builder                      .with_version("4.0".to_string())                      .with_rev(format!("{}", rev)) -                    .build() { -                        Ok(vcard) => { -                            match self.selected_option { -                                DownloadOption::VCard => { -                                    self.download = Some( -                                        Download { -                                            file_name: String::from("VCard.vcs"), -                                            content: vobject::write_component(&vcard), -                                            mime_type: MimeType::VCard, -                                        } -                                    ); -                                }, -                                DownloadOption::QrCode => { -                                    match QrCode::encode_text(&vobject::write_component(&vcard), QrCodeEcc::Low) { -                                        Ok(qr) => self.download = Some( -                                            Download { -                                                file_name: String::from("QR-Code VCard.svg"), -                                                content: qr.to_svg_string(4), -                                                mime_type: MimeType::SVG, -                                            } -                                        ), -                                        Err(_) => self.error = Some( -                                            Error{ -                                                msg: String::from("Sorry, VCard is too long!"), -                                            } -                                        ), -                                    }; -                                }, -                                _ => (), -                            }; -                        }, -                        Err(err) => self.error = Some( -                            Error{ -                                msg: err.to_string(), +                    .build() +                { +                    Ok(vcard) => { +                        match self.selected_option { +                            DownloadOption::VCard => { +                                self.download = Some(Download { +                                    file_name: String::from("VCard.vcs"), +                                    content: vobject::write_component(&vcard), +                                    mime_type: MimeType::VCard, +                                });                              } -                        ), -                    }; +                            DownloadOption::QrCode => { +                                match QrCode::encode_text( +                                    &vobject::write_component(&vcard), +                                    QrCodeEcc::Low, +                                ) { +                                    Ok(qr) => { +                                        self.download = Some(Download { +                                            file_name: String::from("QR-Code VCard.svg"), +                                            content: qr.to_svg_string(4), +                                            mime_type: MimeType::SVG, +                                        }) +                                    } +                                    Err(_) => { +                                        self.error = Some(Error { +                                            msg: String::from("Sorry, VCard is too long!"), +                                        }) +                                    } +                                }; +                            } +                            _ => (), +                        }; +                    } +                    Err(err) => { +                        self.error = Some(Error { +                            msg: err.to_string(), +                        }) +                    } +                };                  match self.vcard_data.get_mut() {                      Some(vcard_data) => *vcard_data = VCardData::new(), @@ -449,8 +422,7 @@ impl Component for MainView {                  };                  shouldrender = true; - -            }, +            }              Msg::Nope => shouldrender = false,          }; @@ -460,7 +432,7 @@ impl Component for MainView {          if self.error.is_some() {              self.download = None;          } -         +          shouldrender      } @@ -469,20 +441,17 @@ impl Component for MainView {      }      fn view(&self) -> Html { - -        let download_options = self.link.callback(|e: ChangeData| -            match e { -                ChangeData::Select(v) => match v.value().as_str() { -                    "vcard" => Msg::ChangeDownloadOption(DownloadOption::VCard), -                    "pdf" => Msg::ChangeDownloadOption(DownloadOption::PDF), -                    "qrcode" => Msg::ChangeDownloadOption(DownloadOption::QrCode), -                    _ => Msg::Nope, -                }, +        let download_options = self.link.callback(|e: ChangeData| match e { +            ChangeData::Select(v) => match v.value().as_str() { +                "vcard" => Msg::ChangeDownloadOption(DownloadOption::VCard), +                "pdf" => Msg::ChangeDownloadOption(DownloadOption::PDF), +                "qrcode" => Msg::ChangeDownloadOption(DownloadOption::QrCode),                  _ => Msg::Nope, -            } -        ); +            }, +            _ => Msg::Nope, +        }); -        html!{ +        html! {              <>                  <main>                      <section class="hero"> @@ -502,9 +471,9 @@ impl Component for MainView {                              {                                  for self.name_links.iter().map(|link|                                      html!{ -                                        <NameView   weak_link=link  +                                        <NameView   weak_link=link                                                      generated=self.link.callback( -                                                        |n: Name|  +                                                        |n: Name|                                                              Msg::GeneratedName(n)                                                      )                                          /> @@ -574,7 +543,7 @@ impl Component for MainView {                                          <option value="qrcode">{ "QR Code" }</option>                                      </select>                                  </div> -                                 +                                  { self.render_download() }                              </div> @@ -601,7 +570,7 @@ impl Component for MainView {  impl MainView {      fn render_error(&self) -> Html { -        html!{ +        html! {              <>                  {                      match &self.error { @@ -622,13 +591,13 @@ impl MainView {          if self.download.is_some() {              let download = self.download.as_ref().unwrap(); -            html!{ +            html! {                  <a href=download.as_data_link() download=download.file_name class="button is-success level-item" >                      { "Download" }                  </a>              }          } else { -            html!{} +            html! {}          }      }      fn render_preview(&self) -> Html { @@ -636,53 +605,71 @@ impl MainView {              let download = self.download.as_ref().unwrap();              match download.mime_type { -                MimeType::PDF => html!{ +                MimeType::PDF => html! {                      <iframe src=download.as_data_link() alt="PDF Preview" width="400" height="550"/>                  },                  MimeType::VCard => { -                    html!{ +                    html! {                          <pre>                              <code> { download.content.clone() } </code>                          </pre>                      }                  } -                MimeType::SVG => html!{ +                MimeType::SVG => html! {                      <img src=download.as_data_link() alt="Image Preview" class="image is-square" width="300" height="300"/>                  },              }          } else { -            html!{} +            html! {}          }      } -    fn generate_pdf(&self) -> Result<String, ()>{ -        let regular_bytes = include_bytes!("/usr/share/fonts/liberation/LiberationSans-Regular.ttf"); -        let regular_font_data = fonts::FontData::new(regular_bytes.to_vec(), Some(printpdf::BuiltinFont::Helvetica)).expect("font data should be correct"); +    fn generate_pdf(&self) -> Result<String, ()> { +        let regular_bytes = +            include_bytes!("/usr/share/fonts/liberation/LiberationSans-Regular.ttf"); +        let regular_font_data = fonts::FontData::new( +            regular_bytes.to_vec(), +            Some(printpdf::BuiltinFont::Helvetica), +        ) +        .expect("font data should be correct");          let bold_bytes = include_bytes!("/usr/share/fonts/liberation/LiberationSans-Bold.ttf"); -        let bold_font_data = fonts::FontData::new(bold_bytes.to_vec(), Some(printpdf::BuiltinFont::HelveticaBold)).expect("font data should be correct"); +        let bold_font_data = fonts::FontData::new( +            bold_bytes.to_vec(), +            Some(printpdf::BuiltinFont::HelveticaBold), +        ) +        .expect("font data should be correct");          let italic_bytes = include_bytes!("/usr/share/fonts/liberation/LiberationSans-Italic.ttf"); -        let italic_font_data = fonts::FontData::new(italic_bytes.to_vec(), Some(printpdf::BuiltinFont::HelveticaOblique)).expect("font data should be correct"); - -        let bold_italic_bytes = include_bytes!("/usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf"); -        let bold_italic_font_data = fonts::FontData::new(bold_italic_bytes.to_vec(), Some(printpdf::BuiltinFont::HelveticaBoldOblique)).expect("font data should be correct"); - -        let font_family = fonts::FontFamily{  -            regular: regular_font_data,  -            bold: bold_font_data,  -            italic: italic_font_data,  -            bold_italic: bold_italic_font_data  +        let italic_font_data = fonts::FontData::new( +            italic_bytes.to_vec(), +            Some(printpdf::BuiltinFont::HelveticaOblique), +        ) +        .expect("font data should be correct"); + +        let bold_italic_bytes = +            include_bytes!("/usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf"); +        let bold_italic_font_data = fonts::FontData::new( +            bold_italic_bytes.to_vec(), +            Some(printpdf::BuiltinFont::HelveticaBoldOblique), +        ) +        .expect("font data should be correct"); + +        let font_family = fonts::FontFamily { +            regular: regular_font_data, +            bold: bold_font_data, +            italic: italic_font_data, +            bold_italic: bold_italic_font_data,          };          let mut doc = genpdf::Document::new(font_family);          doc.set_title("BCard test");          doc.set_minimal_conformance(); -         +          let mut decorator = genpdf::SimplePageDecorator::new();          decorator.set_margins(10);          doc.set_page_decorator(decorator); -         +          doc.set_line_spacing(1.25);          doc.push( @@ -704,9 +691,9 @@ impl MainView {      }      fn get_subcomponent_count(&self) -> usize {          self.name_links.len() -        + self.address_links.len() -        + self.telephone_links.len() -        + self.dates_links.len() -        + self.organizational_links.len() +            + self.address_links.len() +            + self.telephone_links.len() +            + self.dates_links.len() +            + self.organizational_links.len()      } -}
\ No newline at end of file +} diff --git a/src/view/mod.rs b/src/view/mod.rs index 0751c53..cbff0fd 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -1,27 +1,30 @@ -use yew::prelude::*; +use crate::viewmodel::*;  use std::cell::RefCell;  use std::ops::Deref;  use std::rc::Rc; -use crate::viewmodel::*; +use yew::prelude::*; -pub mod main; -pub mod name;  pub mod address; -pub mod telephone;  pub mod dates; +pub mod main; +pub mod name;  pub mod organizational; +pub mod telephone;  #[derive(Clone, PartialEq, Properties)] -pub struct InputProps<O, C>  -    where   O: VCardPropertyInputObject<C> + Clone, -            C: VCardPropertyInputComponent<O> + Clone  +pub struct InputProps<O, C> +where +    O: VCardPropertyInputObject<C> + Clone, +    C: VCardPropertyInputComponent<O> + Clone,  {      pub generated: Callback<O>,      pub weak_link: WeakComponentLink<C>,  }  /// Trait for types that represent an input component for a vcard property. -pub trait VCardPropertyInputComponent<T: VCardPropertyInputObject<Self>>: Component + Clone + PartialEq { +pub trait VCardPropertyInputComponent<T: VCardPropertyInputObject<Self>>: +    Component + Clone + PartialEq +{      /// Returns the object containing the input data.      fn get_input_object(&self) -> T;      /// Getter function for the title of the component @@ -30,7 +33,7 @@ pub trait VCardPropertyInputComponent<T: VCardPropertyInputObject<Self>>: Compon      fn get_error(&self) -> Option<Error>;      /// Returns the error as `Html`      fn render_error(&self) -> Html { -        html!{ +        html! {              <>                  {                      if self.get_error().is_some() { @@ -75,4 +78,4 @@ impl<COMP: Component> PartialEq for WeakComponentLink<COMP> {      fn eq(&self, other: &Self) -> bool {          Rc::ptr_eq(&self.0, &other.0)      } -}
\ No newline at end of file +} diff --git a/src/view/name.rs b/src/view/name.rs index 4976e7d..4b7089b 100644 --- a/src/view/name.rs +++ b/src/view/name.rs @@ -1,28 +1,28 @@ +use super::VCardPropertyInputComponent;  use crate::view::InputProps; -use yew::prelude::*; -use yewtil::NeqAssign; -use crate::viewmodel::Error;  use crate::viewmodel::name::*; +use crate::viewmodel::Error;  use crate::viewmodel::VCardPropertyInputObject; -use super::VCardPropertyInputComponent; +use yew::prelude::*; +use yewtil::NeqAssign; -type Props = InputProps<Name,NameView>; +type Props = InputProps<Name, NameView>;  /// View Component for a `name` field -///  +///  /// # Examples -///  +///  /// ```compile_fail  /// let html = html!{ -///     <NameView   weak_link=some_weak_component_link  +///     <NameView   weak_link=some_weak_component_link  ///                 generated=self.link.callback( -///                     |n: Irc<Name>|  +///                     |n: Irc<Name>|  ///                     Msg::GeneratedName(some_name)  ///                 )  ///     />  /// };  /// ``` -#[derive(Clone,PartialEq)] +#[derive(Clone, PartialEq)]  pub struct NameView {      props: Props,      value: Name, @@ -71,17 +71,17 @@ impl Component for NameView {              Msg::UpdateSuffix(s) => self.value.suffix = s,              Msg::Generate => {                  self.props.generated.emit(self.value.clone()); -            }, +            }          };          true      } -    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {  +    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {          self.props.neq_assign(props)      }      fn view(&self) -> yew::virtual_dom::VNode {          let link = self.props.weak_link.borrow().clone().unwrap(); -        html!{ +        html! {              <div class="box">                  { self.render_error() } @@ -92,4 +92,4 @@ impl Component for NameView {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/view/organizational.rs b/src/view/organizational.rs index e6636ec..7f2ca69 100644 --- a/src/view/organizational.rs +++ b/src/view/organizational.rs @@ -1,15 +1,15 @@ -use crate::viewmodel::utility::File; -use yew::prelude::*; -use yewtil::NeqAssign; -use crate::viewmodel::Error; +use super::VCardPropertyInputComponent;  use crate::view::InputProps;  use crate::viewmodel::organizational::*; +use crate::viewmodel::utility::File; +use crate::viewmodel::Error;  use crate::viewmodel::VCardPropertyInputObject; -use super::VCardPropertyInputComponent; +use yew::prelude::*; +use yewtil::NeqAssign; -type Props = InputProps<Organizational,OrganizationalView>; +type Props = InputProps<Organizational, OrganizationalView>; -#[derive(Clone,PartialEq)] +#[derive(Clone, PartialEq)]  pub struct OrganizationalView {      props: Props,      value: Organizational, @@ -60,7 +60,7 @@ impl Component for OrganizationalView {              Msg::UpdateRelated(r) => self.value.related = r,              Msg::Generate => {                  self.props.generated.emit(self.value.clone()); -            }, +            }          };          true      } @@ -70,7 +70,7 @@ impl Component for OrganizationalView {      fn view(&self) -> yew::virtual_dom::VNode {          let link = self.props.weak_link.borrow().clone().unwrap(); -        html!{ +        html! {              <div class="box">                  { self.render_error() } @@ -81,4 +81,4 @@ impl Component for OrganizationalView {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/view/telephone.rs b/src/view/telephone.rs index dc93632..68389ba 100644 --- a/src/view/telephone.rs +++ b/src/view/telephone.rs @@ -1,28 +1,28 @@ +use super::VCardPropertyInputComponent;  use crate::view::InputProps; -use yew::prelude::*; -use yewtil::NeqAssign; -use crate::viewmodel::Error;  use crate::viewmodel::telephone::*; +use crate::viewmodel::Error;  use crate::viewmodel::VCardPropertyInputObject; -use super::VCardPropertyInputComponent; +use yew::prelude::*; +use yewtil::NeqAssign; -type Props = InputProps<Telephone,TelephoneView>; +type Props = InputProps<Telephone, TelephoneView>;  /// View Component for a `telephone` field -///  +///  /// # Examples -///  +///  /// ```compile_fail  /// let html = html!{ -///     <TelephoneView   weak_link=some_weak_component_link  +///     <TelephoneView   weak_link=some_weak_component_link  ///                 generated=self.link.callback( -///                     |n: Irc<Telephone>|  +///                     |n: Irc<Telephone>|  ///                     Msg::GeneratedTelephone(some_telephone)  ///                 )  ///     />  /// };  /// ``` -#[derive(Clone,PartialEq)] +#[derive(Clone, PartialEq)]  pub struct TelephoneView {      props: Props,      value: Telephone, @@ -85,13 +85,13 @@ impl Component for TelephoneView {          };          true      } -    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {  +    fn change(&mut self, props: <Self as yew::Component>::Properties) -> bool {          self.props.neq_assign(props)      }      fn view(&self) -> yew::virtual_dom::VNode {          let link = self.props.weak_link.borrow().clone().unwrap(); -        html!{ +        html! {              <div class="box">                  { self.render_error() } @@ -102,4 +102,4 @@ impl Component for TelephoneView {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/address.rs b/src/viewmodel/address.rs index 71cc8d3..9542675 100644 --- a/src/viewmodel/address.rs +++ b/src/viewmodel/address.rs @@ -31,15 +31,15 @@ impl VCardPropertyInputObject<AddressView> for Address {      fn get_input_fields(&self, link: &ComponentLink<AddressView>) -> Vec<VCardPropertyInputField> {          let typ = String::from("text");          vec![ -            VCardPropertyInputField::Text{ +            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(),  +                typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Extension".to_string(),                  id: Some("extension".to_string()),                  placeholder: None, @@ -47,7 +47,7 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.extension.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Street".to_string(),                  id: Some("street".to_string()),                  placeholder: None, @@ -55,7 +55,7 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.street.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Locality".to_string(),                  id: Some("locality".to_string()),                  placeholder: None, @@ -63,7 +63,7 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.locality.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Region".to_string(),                  id: Some("region".to_string()),                  placeholder: None, @@ -71,7 +71,7 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.region.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Code".to_string(),                  id: Some("code".to_string()),                  placeholder: None, @@ -79,7 +79,7 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.code.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Country".to_string(),                  id: Some("country".to_string()),                  placeholder: None, @@ -87,13 +87,13 @@ impl VCardPropertyInputObject<AddressView> for Address {                  value: self.country.clone(),                  typ,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Work".to_string(),                  id: Some("work".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleWork),                  value: self.work,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Home".to_string(),                  id: Some("home".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleHome), @@ -102,12 +102,12 @@ impl VCardPropertyInputObject<AddressView> for Address {          ]      }      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() +        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()      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/dates.rs b/src/viewmodel/dates.rs index 28e8bad..7d8d394 100644 --- a/src/viewmodel/dates.rs +++ b/src/viewmodel/dates.rs @@ -1,5 +1,5 @@ -use crate::view::dates::*;  use super::*; +use crate::view::dates::*;  /// Type that represents the vcard `anniversary` and `birthday` properties.  #[derive(Clone, Debug, PartialEq)] @@ -15,10 +15,13 @@ impl VCardPropertyInputObject<DatesView> for Dates {              birthday: String::new(),          }      } -    fn get_input_fields(&self, link: &yew::html::Scope<DatesView>) -> std::vec::Vec<VCardPropertyInputField> { +    fn get_input_fields( +        &self, +        link: &yew::html::Scope<DatesView>, +    ) -> std::vec::Vec<VCardPropertyInputField> {          let typ = String::from("date");          vec![ -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Anniversary".to_string(),                  id: Some("anniversary".to_string()),                  placeholder: None, @@ -26,7 +29,7 @@ impl VCardPropertyInputObject<DatesView> for Dates {                  value: self.anniversary.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Birthday".to_string(),                  id: Some("birthday".to_string()),                  placeholder: None, @@ -37,7 +40,6 @@ impl VCardPropertyInputObject<DatesView> for Dates {          ]      }      fn is_empty(&self) -> bool { -        self.anniversary.is_empty() -        && self.birthday.is_empty() +        self.anniversary.is_empty() && self.birthday.is_empty()      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/mod.rs b/src/viewmodel/mod.rs index 044dbad..0385c61 100644 --- a/src/viewmodel/mod.rs +++ b/src/viewmodel/mod.rs @@ -1,23 +1,24 @@ +use crate::view::VCardPropertyInputComponent; +use crate::viewmodel::utility::File;  use wasm_bindgen::closure::Closure; -use web_sys::FileReader;  use wasm_bindgen::JsCast; -use yew::services::ConsoleService; -use crate::viewmodel::utility::File; +use web_sys::FileReader;  use yew::prelude::*; -use crate::view::VCardPropertyInputComponent; +use yew::services::ConsoleService; -pub mod vcard; -pub mod utility;  pub mod address; -pub mod name; -pub mod telephone;  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  +pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>>: +    Clone + PartialEq +where +    Self: Sized,  {      /// Function for creating a new (and empty) `VCardPropertyInputObject`.      fn new() -> Self; @@ -25,12 +26,12 @@ pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>>: Clone      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!{ +        html! {              <div class="columns is-mobile is-multiline"> -                {  +                {                      for self.get_input_fields(link).iter().map(|field|                          field.render() -                    )  +                    )                  }              </div>          } @@ -40,9 +41,9 @@ pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>>: Clone  }  /// Type for saving error messages. -///  +///  /// More of a placeholder for something better later on. -#[derive(Debug,Clone,PartialEq)] +#[derive(Debug, Clone, PartialEq)]  pub struct Error {      pub msg: String,  } @@ -97,10 +98,16 @@ impl VCardPropertyInputField {              } => 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  +    /// 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 @@ -116,14 +123,19 @@ impl VCardPropertyInputField {              </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 { +    /// 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| +        let onchange = onchange.reform(move |c: ChangeData| {              if let ChangeData::Files(files) = c {                  match files.item(0) { -                    Some(file) => {  +                    Some(file) => {                          let file_reader = FileReader::new().unwrap();                          match file_reader.read_as_data_url(&file) {                              Ok(_) => (), @@ -131,33 +143,33 @@ impl VCardPropertyInputField {                          };                          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(); +                        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, -                                    }) -                                ), +                                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!{ +        }); +        html! {              <div class="field column                          is-one-fifth-widescreen                          is-one-quarter-desktop @@ -192,17 +204,22 @@ impl VCardPropertyInputField {              </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  +    /// 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"  +                            type="checkbox"                              checked=*checked                              onclick=onclick                      /> @@ -211,4 +228,4 @@ impl VCardPropertyInputField {              </div>          }      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/name.rs b/src/viewmodel/name.rs index ee4736f..de0aa81 100644 --- a/src/viewmodel/name.rs +++ b/src/viewmodel/name.rs @@ -2,7 +2,7 @@ use super::*;  use crate::view::name::*;  /// Type that represents a vcard `name` property -///  +///  /// # Examples  /// ```  /// # use bcard_wasm_webapp::viewmodel::name::Name; @@ -13,7 +13,7 @@ use crate::view::name::*;  /// 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)] @@ -35,10 +35,13 @@ impl VCardPropertyInputObject<NameView> for Name {              suffix: String::new(),          }      } -    fn get_input_fields(&self, link: &ComponentLink<NameView>) -> std::vec::Vec<VCardPropertyInputField> { +    fn get_input_fields( +        &self, +        link: &ComponentLink<NameView>, +    ) -> std::vec::Vec<VCardPropertyInputField> {          let typ = String::from("text");          vec![ -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Prefix".to_string(),                  id: Some("prefix".to_string()),                  placeholder: Some("Sir".to_string()), @@ -46,7 +49,7 @@ impl VCardPropertyInputObject<NameView> for Name {                  value: self.prefix.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "First Name".to_string(),                  id: Some("first_name".to_string()),                  placeholder: Some("Arthur".to_string()), @@ -54,7 +57,7 @@ impl VCardPropertyInputObject<NameView> for Name {                  value: self.first_name.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Middle Name".to_string(),                  id: Some("middle_name".to_string()),                  placeholder: Some("Charles".to_string()), @@ -62,7 +65,7 @@ impl VCardPropertyInputObject<NameView> for Name {                  value: self.middle_name.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Last Name".to_string(),                  id: Some("last_name".to_string()),                  placeholder: Some("Clarke".to_string()), @@ -70,7 +73,7 @@ impl VCardPropertyInputObject<NameView> for Name {                  value: self.last_name.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Suffix".to_string(),                  id: Some("suffix".to_string()),                  placeholder: Some("CBE FRAS".to_string()), @@ -81,11 +84,11 @@ impl VCardPropertyInputObject<NameView> for Name {          ]      }      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() +        self.prefix.is_empty() +            && self.first_name.is_empty() +            && self.middle_name.is_empty() +            && self.last_name.is_empty() +            && self.suffix.is_empty()      }  } @@ -113,4 +116,4 @@ impl Name {          full_name      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/organizational.rs b/src/viewmodel/organizational.rs index c8f7164..72b19d2 100644 --- a/src/viewmodel/organizational.rs +++ b/src/viewmodel/organizational.rs @@ -1,7 +1,7 @@ -use crate::view::organizational::*;  use super::*; +use crate::view::organizational::*; -#[derive(Clone,Debug,PartialEq)] +#[derive(Clone, Debug, PartialEq)]  pub struct Organizational {      pub org: String,      pub logo: Option<File>, @@ -22,10 +22,13 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {              related: String::new(),          }      } -    fn get_input_fields(&self, link: &yew::html::Scope<OrganizationalView>) -> std::vec::Vec<VCardPropertyInputField> { +    fn get_input_fields( +        &self, +        link: &yew::html::Scope<OrganizationalView>, +    ) -> std::vec::Vec<VCardPropertyInputField> {          let typ = String::from("text");          vec![ -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Organisation".to_string(),                  id: Some("org".to_string()),                  placeholder: None, @@ -33,46 +36,14 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {                  value: self.org.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::File{ // TODO: Add Upload for logo +            VCardPropertyInputField::File { +                // TODO: Add Upload for logo                  label: "Logo".to_string(),                  name: "logo".to_string(), -                callback: link.callback(|file: Option<File>|  -                    /* -                    if let ChangeData::Files(files) = c { -                        match files.item(0) { -                            Some(file) => {  -                                let filereader = match FileReaderSync::new() { -                                    Ok(reader) => reader, -                                    Err(_) => { -                                        ConsoleService::warn("Couldn't create new filereader."); -                                        return Msg::UpdateLogo(None) -                                    }, -                                }; -                                let content = match filereader.read_as_data_url(&file) { -                                    Ok(content) => content, -                                    Err(_) => { -                                        ConsoleService::warn("Error: Couldn't get file as data url."); -                                        return Msg::UpdateLogo(None) -                                    }, -                                }; -                                Msg::UpdateLogo( -                                    Some(File { -                                        name: file.name(), -                                        content, -                                    }) -                                ) -                            }, -                            None => Msg::UpdateLogo(None), -                        } -                    } else { -                        Msg::UpdateLogo(None) -                    } -                    */ -                    Msg::UpdateLogo(file) -                ), +                callback: link.callback(|file: Option<File>| Msg::UpdateLogo(file)),                  value: self.logo.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Title".to_string(),                  id: Some("title".to_string()),                  placeholder: None, @@ -80,7 +51,7 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {                  value: self.title.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Role".to_string(),                  id: Some("role".to_string()),                  placeholder: None, @@ -88,7 +59,7 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {                  value: self.role.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Member".to_string(),                  id: Some("member".to_string()),                  placeholder: None, @@ -96,7 +67,7 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {                  value: self.member.clone(),                  typ: typ.clone(),              }, -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Related".to_string(),                  id: Some("related".to_string()),                  placeholder: None, @@ -107,11 +78,11 @@ impl VCardPropertyInputObject<OrganizationalView> for Organizational {          ]      }      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() +        self.org.is_empty() +            && self.logo.is_none() +            && self.title.is_empty() +            && self.role.is_empty() +            && self.member.is_empty() +            && self.related.is_empty()      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/telephone.rs b/src/viewmodel/telephone.rs index ee616c3..44b938f 100644 --- a/src/viewmodel/telephone.rs +++ b/src/viewmodel/telephone.rs @@ -30,10 +30,13 @@ impl VCardPropertyInputObject<TelephoneView> for Telephone {              text_phone: false,          }      } -    fn get_input_fields(&self, link: &ComponentLink<TelephoneView>) -> Vec<VCardPropertyInputField> { +    fn get_input_fields( +        &self, +        link: &ComponentLink<TelephoneView>, +    ) -> Vec<VCardPropertyInputField> {          let typ = String::from("tel");          vec![ -            VCardPropertyInputField::Text{ +            VCardPropertyInputField::Text {                  label: "Number".to_string(),                  id: Some("number".to_string()),                  placeholder: None, @@ -41,55 +44,55 @@ impl VCardPropertyInputObject<TelephoneView> for Telephone {                  value: self.number.clone(),                  typ,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Work".to_string(),                  id: Some("work".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleWork),                  value: self.work,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Home".to_string(),                  id: Some("home".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleHome),                  value: self.home,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Text".to_string(),                  id: Some("text".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleText),                  value: self.text,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Voice".to_string(),                  id: Some("voice".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleVoice),                  value: self.voice,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Fax".to_string(),                  id: Some("fax".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleFax),                  value: self.fax,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Cell".to_string(),                  id: Some("cell".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleCell),                  value: self.cell,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Video".to_string(),                  id: Some("video".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleVideo),                  value: self.video,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Pager".to_string(),                  id: Some("pager".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::TogglePager),                  value: self.pager,              }, -            VCardPropertyInputField::CheckBox{ +            VCardPropertyInputField::CheckBox {                  label: "Text Phone".to_string(),                  id: Some("text_phone".to_string()),                  onclick: link.callback(|_: MouseEvent| Msg::ToggleTextPhone), @@ -100,4 +103,4 @@ impl VCardPropertyInputObject<TelephoneView> for Telephone {      fn is_empty(&self) -> bool {          self.number.is_empty()      } -}
\ No newline at end of file +} diff --git a/src/viewmodel/utility.rs b/src/viewmodel/utility.rs index cb581ac..617ee45 100644 --- a/src/viewmodel/utility.rs +++ b/src/viewmodel/utility.rs @@ -1,5 +1,3 @@ - -  #[derive(Clone)]  pub struct Download {      pub file_name: String, @@ -40,8 +38,8 @@ pub enum DownloadOption {      QrCode,  } -#[derive(Clone,Debug,PartialEq)] +#[derive(Clone, Debug, PartialEq)]  pub struct File {      pub name: String,      pub content: String, -}
\ No newline at end of file +} diff --git a/src/viewmodel/vcard.rs b/src/viewmodel/vcard.rs index 0d2d6c4..18ce43a 100644 --- a/src/viewmodel/vcard.rs +++ b/src/viewmodel/vcard.rs @@ -1,8 +1,8 @@ -use crate::viewmodel::organizational::Organizational; -use crate::viewmodel::dates::Dates; -use crate::viewmodel::telephone::Telephone;  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)] @@ -37,4 +37,4 @@ impl VCardData {      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 ); -}
\ No newline at end of file +}  | 
