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: Vec<Tax>,
87 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}