summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjelemux <jeremias.weber@protonmail.com>2021-03-05 20:09:25 +0100
committerjelemux <jeremias.weber@protonmail.com>2021-03-05 20:09:25 +0100
commited19bef94a247d3eb501ae9f3bcd9496be229d80 (patch)
tree7762283853371daa8b73a8ece1ae54a37e10c4a0
parent0b777005648985ec6d666efe7fb0094e870ee51e (diff)
downloadwasm-card-ed19bef94a247d3eb501ae9f3bcd9496be229d80.tar.gz
wasm-card-ed19bef94a247d3eb501ae9f3bcd9496be229d80.tar.bz2
get pdf generation to work and refactor code a little
-rw-r--r--src/model/vcard.rs325
-rw-r--r--src/view/main.rs485
2 files changed, 406 insertions, 404 deletions
diff --git a/src/model/vcard.rs b/src/model/vcard.rs
index 4670fe7..ea66224 100644
--- a/src/model/vcard.rs
+++ b/src/model/vcard.rs
@@ -1,9 +1,19 @@
+use vobject::vcard::VcardBuilder;
+use chrono::Local;
+use uuid::Uuid;
+use vobject::Vcard;
use crate::model::property_groups::address::Address;
use crate::model::property_groups::communication::Communication;
use crate::model::property_groups::name::Name;
use crate::model::property_groups::organizational::Organizational;
use crate::model::property_groups::other_identification::OtherIdentification;
use crate::model::property_groups::telephone::Telephone;
+use vobject::error::Result as VResult;
+use crate::model::VCardPropertyInputGroupObject;
+use boolinator::Boolinator;
+use vobject::parameters;
+use genpdf::Element as _;
+use genpdf::{elements, fonts, style};
/// Type that represents the data structure of a vcard.
#[derive(Clone, Debug)]
@@ -35,10 +45,325 @@ impl VCardData {
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_communication communications => communication: Communication );
make_vec_adder_fn!( fn add_other_identification other_identifications => other_identification: OtherIdentification );
make_vec_adder_fn!( fn add_organizational organizationals => organizational: Organizational );
+
+ pub fn build_vcard(&self) -> VResult<Vcard> {
+
+ let vcard_data = self.clone();
+ let mut builder = VcardBuilder::new();
+
+ for name in vcard_data.names {
+ if !name.is_empty() {
+ 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()),
+ );
+ }
+ }
+
+ for address in vcard_data.addresses {
+ if !address.is_empty() {
+ let mut types = String::new();
+ if address.work {
+ types.push_str("WORK");
+ }
+ if address.home {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ 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()),
+ );
+ }
+ }
+
+ for telephone in vcard_data.telephones {
+ if !telephone.is_empty() {
+ let mut types = String::new();
+ if telephone.work {
+ types.push_str("WORK");
+ }
+ if telephone.home {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("HOME")
+ }
+ if telephone.text {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("TEXT")
+ }
+ if telephone.voice {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("VOICE")
+ }
+ if telephone.fax {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("FAX")
+ }
+ if telephone.cell {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("CELL")
+ }
+ if telephone.video {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("VIDEO")
+ }
+ if telephone.pager {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("PAGER")
+ }
+ if telephone.text_phone {
+ if !types.is_empty() {
+ types.push(',');
+ }
+ types.push_str("TEXTPHONE")
+ }
+
+ let params = if types.is_empty() {
+ parameters!()
+ } else {
+ parameters!("TYPE" => types)
+ };
+
+ builder = builder.with_tel(params, telephone.number.clone());
+ }
+ }
+
+ for communication in vcard_data.communications {
+ if !communication.email_address.is_empty() {
+ builder = builder.with_email(communication.email_address.clone());
+ }
+ if !communication.impp.is_empty() {
+ builder = builder.with_impp(communication.impp.clone());
+ }
+ }
+
+ for other_identification in vcard_data.other_identifications {
+ if !other_identification.nickname.is_empty() {
+ builder =
+ builder.with_nickname(parameters!(), other_identification.nickname);
+ }
+
+ match other_identification.photo {
+ Some(file) => builder = builder.with_photo(parameters!(), file.content),
+ None => (),
+ };
+
+ if !other_identification.anniversary.is_empty() {
+ builder = builder.with_anniversary(other_identification.anniversary);
+ }
+
+ if !other_identification.birthday.is_empty() {
+ builder = builder.with_bday(parameters!(), other_identification.birthday);
+ }
+
+ if !other_identification.gender.is_empty() {
+ builder = builder.with_gender(parameters!(), other_identification.gender);
+ }
+ }
+
+ for organizational in vcard_data.organizationals {
+ if !organizational.org.is_empty() {
+ builder = builder.with_org(vec![organizational.org]);
+ }
+
+ match organizational.logo {
+ Some(file) => builder = builder.with_logo(file.content),
+ None => (),
+ };
+
+ if !organizational.title.is_empty() {
+ builder = builder.with_title(organizational.title);
+ }
+
+ if !organizational.role.is_empty() {
+ builder = builder.with_role(organizational.role);
+ }
+
+ if !organizational.member.is_empty() {
+ builder = builder.with_member(organizational.member);
+ }
+
+ if !organizational.related.is_empty() {
+ builder = builder.with_related(organizational.related);
+ }
+ }
+
+ let uid = format!("urn:uuid:{}", Uuid::new_v4());
+
+ let rev = Local::now().to_string();
+
+ builder
+ .with_version("4.0".to_string())
+ .with_rev(rev)
+ .with_uid(uid)
+ .build()
+ }
+
+ pub 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 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 mut doc = genpdf::Document::new(font_family);
+
+ doc.set_title("wasm-card 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(
+ elements::Paragraph::new("genpdf Demo Document")
+ .aligned(elements::Alignment::Center)
+ .styled(style::Style::new().bold().with_font_size(20)),
+ );
+
+ let mut card_data = elements::Paragraph::new("");
+
+ let vcard_data = self.clone();
+
+ if let Some(name) = vcard_data.names.get(0) {
+ card_data.push_styled(
+ name.generate_fn(),
+ style::Effect::Bold
+ );
+ }
+ card_data.push(
+ ""
+ );
+ if let Some(communication) = vcard_data.communications.get(0) {
+ card_data.push(
+ communication.email_address.clone()
+ );
+ }
+ card_data.push(
+ ""
+ );
+ if let Some(address) = vcard_data.addresses.get(0) {
+ card_data.push(
+ address.street.clone()
+ );
+ card_data.push(
+ format!("{} {} {}", address.code, address.locality, address.extension)
+ );
+ card_data.push(
+ format!("{} {}", address.region, address.country)
+ );
+ }
+ card_data.push(
+ ""
+ );
+ for telephone in vcard_data.telephones {
+ card_data.push(
+ telephone.number
+ );
+ }
+
+ let framed_card_data = elements::FramedElement::new(
+ card_data
+ );
+
+ let mut table = elements::TableLayout::new(vec![1,1]);
+ table.set_cell_decorator(
+ elements::FrameCellDecorator::new(false, false, false)
+ );
+ for _i in 0..4 {
+ table
+ .row()
+ .element(framed_card_data.clone())
+ .element(framed_card_data.clone())
+ .push()
+ .expect("invalid table row");
+ }
+
+ doc.push(table);
+
+ // TODO fill doc with real data
+
+ let mut buf: Vec<u8> = Vec::new();
+ match doc.render(&mut buf) {
+ Ok(_) => Ok(match String::from_utf8(buf) {
+ Ok(s) => s,
+ Err(_) => return Err(()),
+ }),
+ Err(_) => Err(()),
+ }
+ }
}
diff --git a/src/view/main.rs b/src/view/main.rs
index 40aaa34..3eb9677 100644
--- a/src/view/main.rs
+++ b/src/view/main.rs
@@ -7,18 +7,10 @@ use crate::model::property_groups::telephone::*;
use crate::model::utility::*;
use crate::model::vcard::VCardData;
use crate::model::Error;
-use crate::model::VCardPropertyInputGroupObject;
use crate::view::property_group::PropertyGroupInputComponent;
use crate::view::weak_links::WeakComponentLink;
-use boolinator::Boolinator;
-use chrono::prelude::*;
-use genpdf::Element as _;
-use genpdf::{elements, fonts, style};
use qrcodegen::QrCode;
use qrcodegen::QrCodeEcc;
-use uuid::Uuid;
-use vobject::parameters;
-use vobject::vcard::VcardBuilder;
use yew::prelude::*;
use yew::services::ConsoleService;
use yewtil::ptr::Mrc;
@@ -156,64 +148,36 @@ impl Component for MainView {
false
}
Msg::Generate => {
- 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(NameMsg::Generate);
- }
-
- for address_link in self.address_links.iter() {
- let address_link = address_link.borrow().clone().unwrap();
- address_link.send_message(AddressMsg::Generate);
- }
+
+ for name_link in self.name_links.iter() {
+ let name_link = name_link.borrow().clone().unwrap();
+ name_link.send_message(NameMsg::Generate);
+ }
- for telephone_link in self.telephone_links.iter() {
- let telephone_link = telephone_link.borrow().clone().unwrap();
- telephone_link.send_message(TelephoneMsg::Generate);
- }
+ for address_link in self.address_links.iter() {
+ let address_link = address_link.borrow().clone().unwrap();
+ address_link.send_message(AddressMsg::Generate);
+ }
- for other_identifications_link in self.other_identifications_links.iter() {
- let other_identifications_link =
- other_identifications_link.borrow().clone().unwrap();
- other_identifications_link.send_message(OtherIdentificationMsg::Generate)
- }
+ for telephone_link in self.telephone_links.iter() {
+ let telephone_link = telephone_link.borrow().clone().unwrap();
+ telephone_link.send_message(TelephoneMsg::Generate);
+ }
- for organizational_link in self.organizational_links.iter() {
- let organizational_link = organizational_link.borrow().clone().unwrap();
- organizational_link.send_message(OrganizationalMsg::Generate)
- }
+ for other_identifications_link in self.other_identifications_links.iter() {
+ let other_identifications_link =
+ other_identifications_link.borrow().clone().unwrap();
+ other_identifications_link.send_message(OtherIdentificationMsg::Generate)
+ }
- for communcation_link in self.communcation_links.iter() {
- let communcation_link = communcation_link.borrow().clone().unwrap();
- communcation_link.send_message(CommunicationMsg::Generate)
- }
+ for organizational_link in self.organizational_links.iter() {
+ let organizational_link = organizational_link.borrow().clone().unwrap();
+ organizational_link.send_message(OrganizationalMsg::Generate)
}
- if self.selected_option == DownloadOption::PDF {
- match self.generate_pdf() {
- Ok(pdf) => {
- let mut vcard_name = String::new();
- if let Some(vcard_data) = self.vcard_data.get_mut() {
- if let Some(name) = vcard_data.names.get(0) {
- vcard_name = name.generate_fn();
- }
- }
- self.download = Some(
- Download {
- file_name: format!("Visitenkarten {}.pdf", vcard_name),
- content: pdf,
- mime_type: MimeType::PDF,
- }
- );
- },
- Err(_) => self.error = Some(
- Error {
- msg: String::from("Unexpected error while generating the PDF. Please contact me about it.")
- }
- ),
- }
+ for communcation_link in self.communcation_links.iter() {
+ let communcation_link = communcation_link.borrow().clone().unwrap();
+ communcation_link.send_message(CommunicationMsg::Generate)
}
true
@@ -291,229 +255,71 @@ impl Component for MainView {
Msg::GenerationComplete => {
self.answer_count = 0;
- let vcard_data = self.vcard_data.clone_inner();
-
- let mut builder = VcardBuilder::new();
-
- for name in vcard_data.names {
- if !name.is_empty() {
- 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()),
- );
- }
- }
-
- for address in vcard_data.addresses {
- if !address.is_empty() {
- let mut types = String::new();
- if address.work {
- types.push_str("WORK");
- }
- if address.home {
- if !types.is_empty() {
- types.push(',');
+ if let DownloadOption::PDF = self.selected_option {
+ match self.vcard_data.generate_pdf() {
+ Ok(pdf) => {
+ let mut vcard_name = String::new();
+ if let Some(vcard_data) = self.vcard_data.get_mut() {
+ if let Some(name) = vcard_data.names.get(0) {
+ vcard_name = name.generate_fn();
+ }
}
- 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()),
- );
- }
- }
-
- for telephone in vcard_data.telephones {
- if !telephone.is_empty() {
- let mut types = String::new();
- if telephone.work {
- types.push_str("WORK");
- }
- if telephone.home {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("HOME")
- }
- if telephone.text {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("TEXT")
- }
- if telephone.voice {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("VOICE")
- }
- if telephone.fax {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("FAX")
- }
- if telephone.cell {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("CELL")
- }
- if telephone.video {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("VIDEO")
- }
- if telephone.pager {
- if !types.is_empty() {
- types.push(',');
+ self.download = Some(
+ Download {
+ file_name: format!("Visitenkarten {}.pdf", vcard_name),
+ content: pdf,
+ mime_type: MimeType::PDF,
+ }
+ );
+ },
+ Err(_) => self.error = Some(
+ Error {
+ msg: String::from("Unexpected error while generating the PDF. Please contact me about it.")
}
- types.push_str("PAGER")
+ ),
+ };
+ } else {
+ match self.vcard_data.build_vcard() {
+ 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!"),
+ })
+ }
+ };
+ }
+ _ => (),
+ };
}
- if telephone.text_phone {
- if !types.is_empty() {
- types.push(',');
- }
- types.push_str("TEXTPHONE")
+ Err(err) => {
+ self.error = Some(Error {
+ msg: err.to_string(),
+ })
}
-
- let params = if types.is_empty() {
- parameters!()
- } else {
- parameters!("TYPE" => types)
- };
-
- builder = builder.with_tel(params, telephone.number.clone());
- }
- }
-
- for communication in vcard_data.communications {
- if !communication.email_address.is_empty() {
- builder = builder.with_email(communication.email_address.clone());
- }
- if !communication.impp.is_empty() {
- builder = builder.with_impp(communication.impp.clone());
- }
- }
-
- for other_identification in vcard_data.other_identifications {
- if !other_identification.nickname.is_empty() {
- builder =
- builder.with_nickname(parameters!(), other_identification.nickname);
- }
-
- match other_identification.photo {
- Some(file) => builder = builder.with_photo(parameters!(), file.content),
- None => (),
};
-
- if !other_identification.anniversary.is_empty() {
- builder = builder.with_anniversary(other_identification.anniversary);
- }
-
- if !other_identification.birthday.is_empty() {
- builder = builder.with_bday(parameters!(), other_identification.birthday);
- }
-
- if !other_identification.gender.is_empty() {
- builder = builder.with_gender(parameters!(), other_identification.gender);
- }
- }
-
- for organizational in vcard_data.organizationals {
- if !organizational.org.is_empty() {
- builder = builder.with_org(vec![organizational.org]);
- }
-
- match organizational.logo {
- Some(file) => builder = builder.with_logo(file.content),
- None => (),
- };
-
- if !organizational.title.is_empty() {
- builder = builder.with_title(organizational.title);
- }
-
- if !organizational.role.is_empty() {
- builder = builder.with_role(organizational.role);
- }
-
- if !organizational.member.is_empty() {
- builder = builder.with_member(organizational.member);
- }
-
- if !organizational.related.is_empty() {
- builder = builder.with_related(organizational.related);
- }
}
- let uid = format!("urn:uuid:{}", Uuid::new_v4());
-
- let rev = Local::now().to_string();
-
- match builder
- .with_version("4.0".to_string())
- .with_rev(rev)
- .with_uid(uid)
- .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(),
None => ConsoleService::info("Couldn't reset VCardData"),
@@ -810,135 +616,6 @@ impl MainView {
}
}
- 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 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 mut doc = genpdf::Document::new(font_family);
-
- doc.set_title("wasm-card 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(
- elements::Paragraph::new("genpdf Demo Document")
- .aligned(elements::Alignment::Center)
- .styled(style::Style::new().bold().with_font_size(20)),
- );
-
- let mut card_data = elements::Paragraph::new("");
-
- if let Ok(vcard_data) = self.vcard_data.irc().try_unwrap() {
- if let Some(name) = vcard_data.names.get(0) {
- card_data.push_styled(
- name.generate_fn(),
- style::Effect::Bold
- );
- }
- card_data.push(
- ""
- );
- if let Some(communication) = vcard_data.communications.get(0) {
- card_data.push(
- communication.email_address.clone()
- );
- }
- card_data.push(
- ""
- );
- if let Some(address) = vcard_data.addresses.get(0) {
- card_data.push(
- address.street.clone()
- );
- card_data.push(
- format!("{} {} {}", address.code, address.locality, address.extension)
- );
- card_data.push(
- format!("{} {}", address.region, address.country)
- );
- }
- card_data.push(
- ""
- );
- for telephone in vcard_data.telephones {
- card_data.push(
- telephone.number
- );
- }
- } else {
- ConsoleService::log("Could not unwrap vcard_data.");
- }
-
- let framed_card_data = elements::FramedElement::new(
- card_data
- );
-
- let mut table = elements::TableLayout::new(vec![1,1]);
- table.set_cell_decorator(
- elements::FrameCellDecorator::new(false, false, false)
- );
- for _i in 0..4 {
- table
- .row()
- .element(framed_card_data.clone())
- .element(framed_card_data.clone())
- .push()
- .expect("invalid table row");
- }
-
- doc.push(table);
-
- // TODO fill doc with real data
-
- let mut buf: Vec<u8> = Vec::new();
- match doc.render(&mut buf) {
- Ok(_) => Ok(match String::from_utf8(buf) {
- Ok(s) => s,
- Err(_) => return Err(()),
- }),
- Err(_) => Err(()),
- }
- }
-
fn get_subcomponent_count(&self) -> usize {
self.name_links.len()
+ self.address_links.len()