Skip to content

Commit

Permalink
feat: use a custom builder pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
d-kuen committed May 3, 2024
1 parent 0f064d3 commit 7da266e
Show file tree
Hide file tree
Showing 13 changed files with 756 additions and 418 deletions.
60 changes: 23 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,30 @@
## Example

```rust
Invoice {
generating_system: "test",
invoice_currency: "EUR",
document_title: "An invoice",
language: "de",
invoice_number: "993433000298",
invoice_date: "2020-01-01",
biller: Biller {
vat_identification_number: "ATU51507409",
..Default::default()
},
invoice_recipient: InvoiceRecipient {
vat_identification_number: "ATU18708634",
..Default::default()
},
details: Details {
items: vec![
DetailsItem {
description: vec!["Schraubenzieher"],
quantity: dec!(100),
unit: "STK",
unit_price: dec!(10.20),
tax_item: TaxItem {
tax_percent: dec!(20),
tax_category: TaxCategory::S,
},
..Default::default()
},
],
},
..Default::default()
}
Invoice::new(
"test",
"EUR",
"993433000298",
"2020-01-01",
Biller::new("ATU51507409"),
InvoiceRecipient::new("ATU18708634"),
)
.with_item(
DetailsItem::new(
dec!(100),
"STK",
dec!(10.20),
TaxItem::new(dec!(20), TaxCategory::S),
)
.with_description("Schraubenzieher")
)
.with_document_title("An invoice")
.with_language("de")
.with_payment_method(
PaymentMethodPaymentCard {
primary_account_number: "123456*4321",
card_holder_name: Some("Name"),
},
Some("Comment"),
PaymentMethod::payment_card(
PaymentMethodPaymentCard::new("123456*4321").with_card_holder_name("Name"),
)
.with_comment("Comment"),
)
.to_xml_string()
.unwrap(); // returns "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Invoice>...</Invoice>"
Expand Down
58 changes: 49 additions & 9 deletions src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,57 @@ use crate::xml::XmlElement;

#[derive(Default)]
pub struct Address<'a> {
pub name: &'a str,
pub street: Option<&'a str>,
pub town: &'a str,
pub zip: &'a str,
pub country: &'a str,
pub country_code: Option<&'a str>,
pub phone: Option<Vec<&'a str>>,
pub email: Option<Vec<&'a str>>,
name: &'a str,
street: Option<&'a str>,
town: &'a str,
zip: &'a str,
country: &'a str,
country_code: Option<&'a str>,
phone: Option<Vec<&'a str>>,
email: Option<Vec<&'a str>>,
}

impl Address<'_> {
impl<'a> Address<'a> {
pub fn new(name: &'a str, town: &'a str, zip: &'a str, country: &'a str) -> Address<'a> {
Address {
name,
town,
zip,
country,
..Default::default()
}
}

pub fn with_street(mut self, street: &'a str) -> Self {
self.street = Some(street);
self
}

pub fn with_country_code(mut self, country_code: &'a str) -> Self {
self.country_code = Some(country_code);
self
}

pub fn with_phone(mut self, phone_number: &'a str) -> Self {
let mut phone_numbers = match self.phone {
Some(p) => p,
None => vec![],
};
phone_numbers.push(phone_number);
self.phone = Some(phone_numbers);
self
}

pub fn with_email(mut self, email_address: &'a str) -> Self {
let mut email_addresses = match self.email {
Some(e) => e,
None => vec![],
};
email_addresses.push(email_address);
self.email = Some(email_addresses);
self
}

pub fn as_xml(&self) -> XmlElement {
let mut e = XmlElement::new("Address").with_text_element("Name", self.name);

Expand Down
42 changes: 36 additions & 6 deletions src/biller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,44 @@ use crate::{

#[derive(Default)]
pub struct Biller<'a> {
pub vat_identification_number: &'a str,
pub further_identification: Option<Vec<FurtherIdentification<'a>>>,
pub order_reference: Option<OrderReference<'a>>,
pub address: Option<Address<'a>>,
pub contact: Option<Contact<'a>>,
vat_identification_number: &'a str,
further_identification: Option<Vec<FurtherIdentification<'a>>>,
order_reference: Option<OrderReference<'a>>,
address: Option<Address<'a>>,
contact: Option<Contact<'a>>,
}

impl Biller<'_> {
impl<'a> Biller<'a> {
pub fn new(vat_identification_number: &str) -> Biller {
Biller {
vat_identification_number,
..Default::default()
}
}

pub fn with_further_identification(
mut self,
further_identification: FurtherIdentification<'a>,
) -> Self {
let mut fi = match self.further_identification {
Some(fi) => fi,
None => vec![],
};
fi.push(further_identification);
self.further_identification = Some(fi);
self
}

pub fn with_address(mut self, address: Address<'a>) -> Self {
self.address = Some(address);
self
}

pub fn with_contact(mut self, contact: Contact<'a>) -> Self {
self.contact = Some(contact);
self
}

pub fn as_xml(&self) -> XmlElement {
let mut e = XmlElement::new("Biller")
.with_text_element("VATIdentificationNumber", self.vat_identification_number);
Expand Down
42 changes: 37 additions & 5 deletions src/contact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,45 @@ use crate::xml::XmlElement;

#[derive(Default)]
pub struct Contact<'a> {
pub salutation: Option<&'a str>,
pub name: &'a str,
pub phone: Option<Vec<&'a str>>,
pub email: Option<Vec<&'a str>>,
salutation: Option<&'a str>,
name: &'a str,
phone: Option<Vec<&'a str>>,
email: Option<Vec<&'a str>>,
}

impl Contact<'_> {
impl<'a> Contact<'a> {
pub fn new(name: &str) -> Contact {
Contact {
name,
..Default::default()
}
}

pub fn with_salutation(mut self, salutation: &'a str) -> Self {
self.salutation = Some(salutation);
self
}

pub fn with_phone(mut self, phone_number: &'a str) -> Self {
let mut phone_numbers = match self.phone {
Some(p) => p,
None => vec![],
};
phone_numbers.push(phone_number);
self.phone = Some(phone_numbers);
self
}

pub fn with_email(mut self, email_address: &'a str) -> Self {
let mut email_addresses = match self.email {
Some(e) => e,
None => vec![],
};
email_addresses.push(email_address);
self.email = Some(email_addresses);
self
}

pub fn as_xml(&self) -> XmlElement {
let mut e = XmlElement::new("Contact");

Expand Down
Loading

0 comments on commit 7da266e

Please sign in to comment.