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