union_table/
union_table.rs

1use html_export::composed::table::from_iterator;
2use html_export::composed::table::AsTable;
3use html_export::elem;
4use html_export::element::*;
5use html_export::head::Head;
6use html_export::tags::*;
7use html_export::thead;
8use html_export::*;
9extern crate html_export;
10
11pub enum Item {
12    BasicItem(BasicItem),
13    DiscountedItem(DiscountedItem),
14}
15
16pub struct BasicItem {
17    name: String,
18    unit_price: f64,
19    quantity: u64,
20}
21
22pub struct DiscountedItem {
23    name: String,
24    unit_price: f64,
25    quantity: u64,
26    unit_discount: f64,
27}
28
29impl BasicItem {
30    pub fn new(name: String, unit_price: f64, quantity: u64) -> Self {
31        Self {
32            name,
33            unit_price,
34            quantity,
35        }
36    }
37
38    pub fn as_row(&self) -> Option<Element> {
39        let mut row = tr!();
40        row += td!() + Element::Text(self.name.clone());
41        row +=
42            td!(attributes = {"colspan" => Some("2")}) + Element::Text(self.unit_price.to_string());
43        row += td!() + Element::Text(self.quantity.to_string());
44        row += td!(attributes = {"colspan" => Some("3")})
45            + Element::Text((self.unit_price * (self.quantity as f64)).to_string());
46        Some(row)
47    }
48}
49
50impl DiscountedItem {
51    pub fn new(name: String, unit_price: f64, quantity: u64, unit_discount: f64) -> Self {
52        Self {
53            name,
54            unit_price,
55            quantity,
56            unit_discount,
57        }
58    }
59    pub fn as_row(&self) -> Option<Element> {
60        let mut row = tr!();
61        row += td!() + Element::Text(self.name.clone());
62        row += td!() + Element::Text(self.unit_price.to_string());
63        row += td!() + Element::Text(self.unit_discount.to_string());
64        row += td!() + Element::Text(self.quantity.to_string());
65        row += td!() + Element::Text((self.unit_price * (self.quantity as f64)).to_string());
66        row += td!() + Element::Text((self.unit_discount * (self.quantity as f64)).to_string());
67        row += td!()
68            + Element::Text(
69                (self.unit_price * (self.quantity as f64)
70                    - self.unit_discount * (self.quantity as f64))
71                    .to_string(),
72            );
73        Some(row)
74    }
75}
76
77impl AsTable for Item {
78    fn as_table_head(&self) -> Option<html_export::element::Element> {
79        let heading =
80            tr!() + (th!(attributes = {"colspan" => Some("7")}) + (h2!() + text!("Items")));
81        let mut sub_heading = tr!();
82        let mut sub_sub_heading = tr!();
83        sub_heading += th!(attributes = {"rowspan" => Some("2")}) + text!("Name");
84        sub_heading += th!(attributes = {"colspan" => Some("2")}) + text!("Unitary");
85        sub_heading += th!(attributes = {"rowspan" => Some("2")}) + text!("Quantity");
86        sub_heading += th!(attributes = {"colspan" => Some("3")}) + text!("Totals");
87        sub_sub_heading += th!() + text!("Unit price");
88        sub_sub_heading += th!() + text!("Unit discount");
89        sub_sub_heading += th!() + text!("Price");
90        sub_sub_heading += th!() + text!("Discount");
91        sub_sub_heading += th!() + text!("Result");
92
93        Some(thead!() + heading + sub_heading + sub_sub_heading)
94    }
95
96    fn as_table_row(&self) -> Option<html_export::element::Element> {
97        match self {
98            Item::BasicItem(basic_item) => basic_item.as_row(),
99            Item::DiscountedItem(discounted_item) => discounted_item.as_row(),
100        }
101    }
102
103    fn as_table_foot(&self) -> Option<html_export::element::Element> {
104        None
105    }
106}
107
108fn main() {
109    let items = vec![
110        Item::BasicItem(BasicItem::new("Item A".to_string(), 10.0, 3)),
111        Item::BasicItem(BasicItem::new("Item B".to_string(), 11.0, 2)),
112        Item::DiscountedItem(DiscountedItem::new("Item C".to_string(), 20.0, 5, 5.0)),
113        Item::DiscountedItem(DiscountedItem::new("Item D".to_string(), 5.0, 1, 10.0)),
114        Item::BasicItem(BasicItem::new("Item E".to_string(), 100.0, 1)),
115    ];
116    let table = from_iterator(
117        &items,
118        HtmlElementConfig::new_empty(),
119        HtmlElementConfig::new_empty(),
120    )
121    .unwrap();
122    let head = Head::new().with_title("Union table".to_string());
123    export_to_file(
124        "examples_output".to_string(),
125        "union_tables.html".to_string(),
126        head,
127        vec![table],
128    )
129    .unwrap();
130}