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
60impl FromStr for Country {
61 type Err = &'static str;
62
63 fn from_str(s: &str) -> Result<Self, Self::Err> {
64 match s.to_ascii_uppercase().as_ref() {
65 "SE" => Ok(Country::SE),
66 _ => Err("no such country"),
67 }
68 }
69}
70
71impl fmt::Display for Country {
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 f.write_str(match self {
74 Country::SE => "Sweden",
75 })
76 }
77}
78
79#[derive(Debug, Serialize)]
80pub struct CountryInfo {
81 country: Country,
82 taxes: Vec<Tax>,
84 tax_reductions: Vec<TaxReduction>,
86}
87
88impl CountryInfo {
89 pub fn current(country: Country) -> Self {
90 let today = Utc::now().date_naive();
91 Self {
92 country: country,
93 taxes: country.current_taxes(today),
94 tax_reductions: country.current_tax_reductions(today),
95 }
96 }
97}
98
99impl From<Country> for CountryInfo {
100 fn from(country: Country) -> Self {
101 let taxes = country.taxes().to_vec();
102 let tax_reductions = country.tax_reductions().to_vec();
103 Self {
104 country,
105 taxes,
106 tax_reductions,
107 }
108 }
109}