grid_tariffs/
country.rs

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