summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--src/view/address.rs17
-rw-r--r--src/view/main.rs109
-rw-r--r--src/view/mod.rs5
-rw-r--r--src/view/name.rs27
-rw-r--r--src/view/telephone.rs16
-rw-r--r--src/viewmodel/address.rs57
-rw-r--r--src/viewmodel/mod.rs5
-rw-r--r--src/viewmodel/name.rs105
-rw-r--r--src/viewmodel/telephone.rs56
10 files changed, 57 insertions, 342 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0228c75..34eb65f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,7 +17,7 @@ wee_alloc = "0.4.5"
yew-state = "^0.4"
printpdf = "0.3.3"
base64 = "0.13.0"
-vcard = "0.4.7"
+vobject = "^0.7"
genpdf = { path = "../genpdf-rs" }
qrcodegen = "1.6.0"
diff --git a/src/view/address.rs b/src/view/address.rs
index b833518..23b697a 100644
--- a/src/view/address.rs
+++ b/src/view/address.rs
@@ -1,11 +1,11 @@
use super::WeakComponentLink;
use yew::prelude::*;
-use vcard::properties;
use crate::viewmodel::address::*;
use crate::viewmodel::VCardPropertyInputObject;
use super::VCardPropertyInputComponent;
use crate::viewmodel::Error;
+
pub struct AddressView {
props: Props,
value: Address,
@@ -28,11 +28,11 @@ pub enum Msg {
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
- pub generated: Callback<Result<properties::Address,()>>,
+ pub generated: Callback<Address>,
pub weak_link: WeakComponentLink<AddressView>,
}
-impl VCardPropertyInputComponent<properties::Address, Address> for AddressView {
+impl VCardPropertyInputComponent<Address> for AddressView {
fn get_input_object(&self) -> Address {
self.value.clone()
}
@@ -67,16 +67,7 @@ impl Component for AddressView {
Msg::ToggleWork => self.value.work = !self.value.work,
Msg::ToggleHome => self.value.home = !self.value.home,
Generate => {
- match self.value.to_vcard_property() {
- Ok(address) => {
- self.props.generated.emit(Ok(address));
- return false;
- },
- Err(error) => {
- self.props.generated.emit(Err(()));
- self.error = Some(error);
- },
- };
+ self.props.generated.emit(self.value);
},
};
true
diff --git a/src/view/main.rs b/src/view/main.rs
index ce8c283..e926504 100644
--- a/src/view/main.rs
+++ b/src/view/main.rs
@@ -9,8 +9,12 @@ use genpdf::{elements, style, fonts};
use qrcodegen::QrCode;
use qrcodegen::QrCodeEcc;
use yew::prelude::*;
-use vcard::properties;
-use vcard::{VCard, VCardError};
+use vobject::Vcard;
+use vobject::vcard::VcardBuilder;
+use vobject::parameters;
+use crate::viewmodel::name::Name;
+use crate::viewmodel::address::Address;
+use crate::viewmodel::telephone::Telephone;
use crate::viewmodel::utility::*;
@@ -19,7 +23,7 @@ pub struct MainView {
error: Option<Error>,
download: Option<Download>,
selected_option: DownloadOption,
- vcard: Option<VCard>,
+ vcard_builder: VcardBuilder,
name_links: Vec<WeakComponentLink<NameView>>,
address_links: Vec<WeakComponentLink<AddressView>>,
@@ -36,10 +40,10 @@ pub enum Msg {
ChangeDownloadOption(DownloadOption),
Generate,
- GeneratedFormattedName(Result<properties::FormattedName,()>),
- GeneratedName(Result<properties::Name,()>),
- GeneratedAddress(Result<properties::Address,()>),
- GeneratedTelephone(Result<properties::Telephone,()>),
+ GeneratedFormattedName(String),
+ GeneratedName(Name),
+ GeneratedAddress(Address),
+ GeneratedTelephone(Telephone),
GenerationComplete,
Nope,
@@ -55,7 +59,7 @@ impl Component for MainView {
error: None,
download: None,
selected_option: DownloadOption::VCard,
- vcard: None,
+ vcard_builder: VcardBuilder::new(),
name_links: vec![WeakComponentLink::default()],
address_links: vec![WeakComponentLink::default()],
@@ -126,31 +130,7 @@ impl Component for MainView {
self.answer_count += 1;
- match formatted_name {
- Ok(formatted_name) => {
- match &mut self.vcard {
- None => {
- match VCard::from_formatted_name(formatted_name) {
- Ok(vcard) => self.vcard = Some(vcard),
- Err(VCardError::FormatError(err)) => {
- self.error = Some(Error{
- msg: err.to_string(),
- });
- },
- Err(VCardError::EmptyFormatName) => {
- self.error= Some(Error{
- msg: String::from("At least one of the name fields should be filled out."),
- });
- },
- };
- },
- Some(vcard) => {
- vcard.formatted_names.insert(formatted_name);
- },
- };
- },
- Err(_) => (),
- };
+ self.vcard_builder = self.vcard_builder.with_fullname(formatted_name);
shouldrender = true;
},
@@ -158,31 +138,14 @@ impl Component for MainView {
self.answer_count += 1;
- match name {
- Ok(name) => {
- match self.vcard {
- Some(vcard) => {
- match vcard.names {
- Some(names) => {
- names.insert(name);
- },
- None => {
- let names = {
- let mut names = HashSet::new();
- names.insert(name);
-
- names
- };
-
- vcard.names = Some(vcard::Set::from_hash_set(names).unwrap());
- }
- };
- },
- None => (),
- };
- },
- Err(_) => (),
- };
+ self.vcard_builder = self.vcard_builder.with_name(
+ parameters!(),
+ name.last_name.is_empty().then(|| name.last_name),
+ name.first_name.is_empty().then(|| name.first_name),
+ name.middle_name.is_empty().then(|| name.middle_name),
+ name.prefix.is_empty().then(|| name.prefix),
+ name.suffix.is_empty().then(|| name.suffix)
+ );
shouldrender = true;
@@ -191,32 +154,10 @@ impl Component for MainView {
self.answer_count += 1;
- match address {
- Ok(address) => {
- match self.vcard {
- Some(vcard) => {
- match vcard.addresses {
- Some(addresses) => {
- addresses.insert(address);
- },
- None => {
- let addresses = {
- let mut addresses = HashSet::new();
- addresses.insert(address);
-
- addresses
- };
-
- vcard.addresses = Some(vcard::Set::from_hash_set(addresses).unwrap());
- }
- };
- },
- None => (),
- };
- },
- Err(_) => (),
- };
-
+ self.vcard_builder = self.vcard_builder.with_adr(
+ parameters!(),
+ );
+
shouldrender = true;
},
Msg::GeneratedTelephone(telephone) => {
diff --git a/src/view/mod.rs b/src/view/mod.rs
index f208c44..7a64fed 100644
--- a/src/view/mod.rs
+++ b/src/view/mod.rs
@@ -9,10 +9,7 @@ pub mod name;
pub mod address;
pub mod telephone;
-pub trait VCardPropertyInputComponent<P, T>: Component
- where P: vcard::properties::Property,
- T: VCardPropertyInputObject<P, Self>
-{
+pub trait VCardPropertyInputComponent<T: VCardPropertyInputObject<Self>>: Component {
fn get_input_object(&self) -> T;
fn get_title(&self) -> String;
fn get_error(&self) -> Option<Error>;
diff --git a/src/view/name.rs b/src/view/name.rs
index df3fb15..bee9256 100644
--- a/src/view/name.rs
+++ b/src/view/name.rs
@@ -1,7 +1,7 @@
use crate::viewmodel::Error;
use crate::view::WeakComponentLink;
use yew::prelude::*;
-use vcard::properties;
+use vobject::Property;
use crate::viewmodel::name::*;
use crate::viewmodel::VCardPropertyInputObject;
use super::VCardPropertyInputComponent;
@@ -24,12 +24,12 @@ pub enum Msg {
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
- pub generated_name: Callback<Result<properties::Name,()>>,
- pub generated_fn: Callback<Result<properties::FormattedName,()>>,
+ pub generated_name: Callback<Name>,
+ pub generated_fn: Callback<String>,
pub weak_link: WeakComponentLink<NameView>,
}
-impl VCardPropertyInputComponent<properties::Name, Name> for NameView {
+impl VCardPropertyInputComponent<Name> for NameView {
fn get_input_object(&self) -> Name {
self.value.clone()
}
@@ -60,23 +60,8 @@ impl Component for NameView {
Msg::UpdateLastName(l) => self.value.last_name = l,
Msg::UpdateSuffix(s) => self.value.suffix = s,
Generate => {
- match self.value.formatted_name() {
- Ok(formatted_name) => self.props.generated_fn.emit(Ok(formatted_name)),
- Err(error) => {
- self.props.generated_fn.emit(Err(()));
- self.error = Some(error);
- },
- };
- match self.value.to_vcard_property() {
- Ok(name) => {
- self.props.generated_name.emit(Ok(name));
- return false;
- },
- Err(error) => {
- self.props.generated_name.emit(Err(()));
- self.error = Some(error);
- },
- };
+ self.props.generated_fn.emit(self.value.generate_fn());
+ self.props.generated_name.emit(self.value);
},
};
true
diff --git a/src/view/telephone.rs b/src/view/telephone.rs
index a47c610..26d7806 100644
--- a/src/view/telephone.rs
+++ b/src/view/telephone.rs
@@ -1,7 +1,6 @@
use crate::view::WeakComponentLink;
use crate::viewmodel::Error;
use yew::prelude::*;
-use vcard::properties;
use crate::viewmodel::telephone::*;
use crate::viewmodel::VCardPropertyInputObject;
use super::VCardPropertyInputComponent;
@@ -30,11 +29,11 @@ pub enum Msg {
#[derive(Clone, PartialEq, Properties)]
pub struct Props {
- pub generated: Callback<Result<properties::Telephone,()>>,
+ pub generated: Callback<Telephone>,
pub weak_link: WeakComponentLink<TelephoneView>,
}
-impl VCardPropertyInputComponent<properties::Telephone, Telephone> for TelephoneView {
+impl VCardPropertyInputComponent<Telephone> for TelephoneView {
fn get_input_object(&self) -> Telephone {
self.value.clone()
}
@@ -71,16 +70,7 @@ impl Component for TelephoneView {
Msg::TogglePager => self.value.pager = !self.value.pager,
Msg::ToggleTextPhone => self.value.text_phone = !self.value.text_phone,
Msg::Generate => {
- match self.value.to_vcard_property() {
- Ok(telephone) => {
- self.props.generated.emit(Ok(telephone));
- return false;
- },
- Err(error) => {
- self.props.generated.emit(Err(()));
- self.error = Some(error);
- },
- };
+ self.props.generated.emit(self.value);
}
};
true
diff --git a/src/viewmodel/address.rs b/src/viewmodel/address.rs
index b2257bf..61bd464 100644
--- a/src/viewmodel/address.rs
+++ b/src/viewmodel/address.rs
@@ -1,7 +1,3 @@
-use vcard::properties;
-use vcard::parameters;
-use vcard::values::{self, text};
-use std::collections::HashSet;
use super::*;
use crate::view::address::*;
@@ -18,7 +14,7 @@ pub struct Address {
pub home: bool,
}
-impl VCardPropertyInputObject<properties::Address, AddressView> for Address {
+impl VCardPropertyInputObject<AddressView> for Address {
fn new() -> Self {
Self {
post_office_box: String::new(),
@@ -106,55 +102,4 @@ impl VCardPropertyInputObject<properties::Address, AddressView> for Address {
self.code.is_empty() &&
self.country.is_empty()
}
- fn to_vcard_property(&self) -> Result<properties::Address, Error> { // TODO error handling
- let address_value = values::address_value::AddressValue::from_components(
- match self.post_office_box.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.post_office_box).unwrap()),
- },
- match self.extension.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.extension).unwrap()),
- },
- match self.street.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.street).unwrap()),
- },
- match self.locality.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.locality).unwrap()),
- },
- match self.region.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.region).unwrap()),
- },
- match self.code.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.code).unwrap()),
- },
- match self.country.is_empty() {
- true => None,
- false => Some(text::Component::from_str(&self.country).unwrap()),
- },
- );
-
- let mut address = properties::Address::from_address_value(address_value);
-
- let type_values = {
- let mut type_values = HashSet::new();
-
- if self.work {
- type_values.insert(values::type_value::TypeValue::Work);
- }
- if self.home {
- type_values.insert(values::type_value::TypeValue::Home);
- }
-
- vcard::Set::from_hash_set(type_values).unwrap()
- };
-
- address.typ = Some(parameters::typ::Type::from_type_values(type_values));
-
- Ok(address)
- }
} \ No newline at end of file
diff --git a/src/viewmodel/mod.rs b/src/viewmodel/mod.rs
index 9dce01c..cc25d68 100644
--- a/src/viewmodel/mod.rs
+++ b/src/viewmodel/mod.rs
@@ -1,5 +1,5 @@
-use vcard::properties;
use yew::prelude::*;
+use vobject::Property;
use crate::view::VCardPropertyInputComponent;
pub mod address;
@@ -7,7 +7,7 @@ pub mod name;
pub mod telephone;
pub mod utility;
-pub trait VCardPropertyInputObject<P: properties::Property, C: VCardPropertyInputComponent<P, Self>>
+pub trait VCardPropertyInputObject<C: VCardPropertyInputComponent<Self>>
where Self: Sized
{
fn new() -> Self;
@@ -24,7 +24,6 @@ pub trait VCardPropertyInputObject<P: properties::Property, C: VCardPropertyInpu
}
}
fn is_empty(&self) -> bool;
- fn to_vcard_property(&self) -> Result<P, Error>;
}
#[derive(Debug,Clone,PartialEq)]
diff --git a/src/viewmodel/name.rs b/src/viewmodel/name.rs
index e0c3a5b..26beaa1 100644
--- a/src/viewmodel/name.rs
+++ b/src/viewmodel/name.rs
@@ -1,5 +1,3 @@
-use vcard::properties;
-use vcard::values::{self, text};
use super::*;
use crate::view::name::*;
@@ -12,7 +10,7 @@ pub struct Name {
pub suffix: String,
}
-impl VCardPropertyInputObject<properties::Name, NameView> for Name {
+impl VCardPropertyInputObject<NameView> for Name {
fn new() -> Self {
Self {
prefix: String::new(),
@@ -68,107 +66,30 @@ impl VCardPropertyInputObject<properties::Name, NameView> for Name {
self.last_name.is_empty() &&
self.suffix.is_empty()
}
- fn to_vcard_property(&self) -> std::result::Result<properties::Name, Error> {
- let name_value = values::name_value::NameValue::from_components(
- match self.last_name.is_empty() {
- true => None,
- false => Some(
- match text::Component::from_str(&self.last_name) {
- Ok(last_name) => last_name,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in last name."),
- }),
- }
- ),
- },
- match self.first_name.is_empty() {
- true => None,
- false => Some(
- match text::Component::from_str(&self.first_name) {
- Ok(first_name) => first_name,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in first name."),
- }),
- }
- ),
- },
- match self.middle_name.is_empty() {
- true => None,
- false => Some(
- match text::Component::from_str(&self.middle_name) {
- Ok(middle_name) => middle_name,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in middle name."),
- }),
- }
- ),
- },
- match self.prefix.is_empty() {
- true => None,
- false => Some(
- match text::Component::from_str(&self.prefix) {
- Ok(prefix) => prefix,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in prefix."),
- }),
- }
- ),
- },
- match self.suffix.is_empty() {
- true => None,
- false => Some(
- match text::Component::from_str(&self.suffix) {
- Ok(suffix) => suffix,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in suffix."),
- }),
- }
- ),
- },
- );
-
- Ok(properties::Name::from_name_value(name_value))
- }
}
impl Name {
- pub fn formatted_name(&self) -> Result<properties::FormattedName, Error> {
- let mut formatted_name = String::new();
+ pub fn generate_fn(&self) -> String {
+ let full_name = String::new();
- if !self.prefix.is_empty() {
- formatted_name.push_str(&self.prefix);
- }
+ full_name.push_str(&self.prefix);
if !self.first_name.is_empty() {
- formatted_name.push_str(" ");
- formatted_name.push_str(&self.first_name);
+ full_name.push_str(" ");
+ full_name.push_str(&self.first_name);
}
if !self.middle_name.is_empty() {
- formatted_name.push_str(" ");
- formatted_name.push_str(&self.middle_name);
+ full_name.push_str(" ");
+ full_name.push_str(&self.middle_name);
}
if !self.last_name.is_empty() {
- formatted_name.push_str(" ");
- formatted_name.push_str(&self.last_name);
+ full_name.push_str(" ");
+ full_name.push_str(&self.last_name);
}
if !self.suffix.is_empty() {
- formatted_name.push_str(", ");
- formatted_name.push_str(&self.suffix);
- }
-
- if formatted_name.is_empty() {
- return Err(Error{
- msg: String::from("Primary name field must not be empty for the formatted name field to be generated."),
- });
+ full_name.push_str(" ");
+ full_name.push_str(&self.suffix);
}
- let formatted_name = properties::FormattedName::from_text(
- match text::Text::from_string(formatted_name) {
- Ok(formatted_name) => formatted_name,
- Err(_) => return Err(Error{
- msg: String::from("Illegal character in formatted name.") // If I see this right, this error should never occur.
- }),
- }
- );
- Ok(formatted_name)
+ full_name
}
} \ No newline at end of file
diff --git a/src/viewmodel/telephone.rs b/src/viewmodel/telephone.rs
index f90df5d..e5f63f0 100644
--- a/src/viewmodel/telephone.rs
+++ b/src/viewmodel/telephone.rs
@@ -1,6 +1,3 @@
-use vcard::properties;
-use vcard::parameters;
-use vcard::values;
use std::collections::HashSet;
use super::*;
use crate::view::telephone::*;
@@ -20,7 +17,7 @@ pub struct Telephone {
pub text_phone: bool,
}
-impl VCardPropertyInputObject<properties::Telephone, TelephoneView> for Telephone {
+impl VCardPropertyInputObject<TelephoneView> for Telephone {
fn new() -> Self {
Self {
number: String::new(),
@@ -112,55 +109,4 @@ impl VCardPropertyInputObject<properties::Telephone, TelephoneView> for Telephon
self.number.is_empty() &&
self.extension.is_empty()
}
- fn to_vcard_property(&self) -> Result<properties::Telephone, Error> { // TODO error handling
- let mut telephone = properties::Telephone::from_telephone_value(
- values::telephone_value::TelephoneValue::from_telephone_number_str(
- self.number.clone(),
- match self.extension.is_empty() {
- true => None::<&str>,
- false => Some(&self.extension),
- },
- ).unwrap()
- );
-
- let type_values = {
- let mut type_values = HashSet::new();
-
- if self.work {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Work);
- }
- if self.home {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Home);
- }
- if self.text {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Text);
- }
- if self.voice {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Voice);
- }
- if self.fax {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Fax);
- }
- if self.cell {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Cell);
- }
- if self.video {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Video);
- }
- if self.pager {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::Pager);
- }
- if self.text_phone {
- type_values.insert(values::type_value::TypeValueWithTelephoneType::TextPhone);
- }
-
- vcard::Set::from_hash_set(type_values).unwrap()
- };
-
- if let properties::Telephone::TelephoneValue { ref mut typ, .. } = telephone {
- *typ = Some(parameters::typ::TypeWithTelType::from_type_values(type_values));
- }
-
- Ok(telephone)
- }
} \ No newline at end of file