grid_tariffs/
country.rs

1use core::fmt;
2use std::str::FromStr;
3
4use chrono::{NaiveDate, Utc};
5use serde::{Deserialize, Serialize};
6
7use crate::{Money, SE_TAX_REDUCTIONS, SE_TAXES, Tax, TaxAppliedBy, TaxReduction};
8
9#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
10#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
11pub enum Country {
12    SE,
13}
14
15impl Country {
16    pub const fn all() -> &'static [Self] {
17        &[Country::SE]
18    }
19
20    pub const fn taxes(&self) -> &'static [Tax] {
21        match self {
22            Country::SE => SE_TAXES,
23        }
24    }
25
26    pub const fn tax_reductions(&self) -> &'static [TaxReduction] {
27        match self {
28            Country::SE => SE_TAX_REDUCTIONS,
29        }
30    }
31
32    pub fn current_taxes(&self, today: NaiveDate) -> Vec<Tax> {
33        self.taxes()
34            .iter()
35            .filter(|tax| tax.valid_for(today))
36            .copied()
37            .collect()
38    }
39
40    pub fn current_tax_reductions(&self, today: NaiveDate) -> Vec<TaxReduction> {
41        self.tax_reductions()
42            .iter()
43            .filter(|tax| tax.valid_for(today))
44            .copied()
45            .collect()
46    }
47}
48
49impl Country {
50    pub fn code(&self) -> &'static str {
51        match self {
52            Country::SE => "SE",
53        }
54    }
55
56    pub fn english_name(&self) -> &'static str {
57        match self {
58            Country::SE => "Sweden",
59        }
60    }
61}
62
63impl FromStr for Country {
64    type Err = &'static str;
65
66    fn from_str(s: &str) -> Result<Self, Self::Err> {
67        match s.to_ascii_uppercase().as_ref() {
68            "SE" => Ok(Country::SE),
69            _ => Err("no such country"),
70        }
71    }
72}
73
74impl fmt::Display for Country {
75    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76        f.write_str(match self {
77            Country::SE => "SE",
78        })
79    }
80}
81
82#[derive(Debug, Serialize)]
83pub struct CountryInfo {
84    country: Country,
85    /// Taxes applied in this country
86    taxes: Vec<Tax>,
87    /// Tax reductions applied in this country
88    tax_reductions: Vec<TaxReduction>,
89}
90
91impl CountryInfo {
92    pub fn current(country: Country) -> Self {
93        let today = Utc::now().date_naive();
94        Self {
95            country,
96            taxes: country.current_taxes(today),
97            tax_reductions: country.current_tax_reductions(today),
98        }
99    }
100}
101
102impl From<Country> for CountryInfo {
103    fn from(country: Country) -> Self {
104        let taxes = country.taxes().to_vec();
105        let tax_reductions = country.tax_reductions().to_vec();
106        Self {
107            country,
108            taxes,
109            tax_reductions,
110        }
111    }
112}