grid_tariffs/
country.rs

1use core::fmt;
2use std::str::FromStr;
3
4use chrono::NaiveDate;
5use chrono_tz::Tz;
6use serde::{Deserialize, Serialize};
7
8use crate::{currency::Currency, helpers::date};
9
10#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
11#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
12pub enum Country {
13    SE,
14}
15
16impl Country {
17    pub const fn all() -> &'static [Self] {
18        &[Country::SE]
19    }
20
21    pub(crate) const fn vat_rate(&self) -> f64 {
22        match self {
23            Country::SE => 1.25,
24        }
25    }
26
27    pub(crate) const fn add_vat(&self, value: f64) -> f64 {
28        value * self.vat_rate()
29    }
30
31    pub(crate) fn is_holiday(&self, date_naive: NaiveDate) -> bool {
32        SE_HOLIDAYS.contains(&date_naive)
33    }
34
35    pub fn default_currency(&self) -> Currency {
36        match self {
37            Country::SE => Currency::SEK,
38        }
39    }
40
41    pub fn default_timezone(&self) -> Tz {
42        match self {
43            Country::SE => Tz::Europe__Stockholm,
44        }
45    }
46}
47
48impl Country {
49    pub fn code(&self) -> &'static str {
50        match self {
51            Country::SE => "SE",
52        }
53    }
54
55    pub fn english_name(&self) -> &'static str {
56        match self {
57            Country::SE => "Sweden",
58        }
59    }
60}
61
62impl FromStr for Country {
63    type Err = &'static str;
64
65    fn from_str(s: &str) -> Result<Self, Self::Err> {
66        match s.to_ascii_uppercase().as_ref() {
67            "SE" => Ok(Country::SE),
68            _ => Err("no such country"),
69        }
70    }
71}
72
73impl fmt::Display for Country {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        f.write_str(match self {
76            Country::SE => "SE",
77        })
78    }
79}
80
81static SE_HOLIDAYS: &[NaiveDate] = &[
82    date(2025, 1, 1),
83    date(2025, 1, 6),
84    date(2025, 4, 18),
85    date(2025, 4, 20),
86    date(2025, 4, 21),
87    date(2025, 5, 1),
88    date(2025, 5, 29),
89    date(2025, 6, 6),
90    date(2025, 6, 8),
91    date(2025, 6, 21),
92    date(2025, 11, 1),
93    date(2025, 12, 24),
94    date(2025, 12, 25),
95    date(2025, 12, 26),
96    date(2025, 12, 31),
97    date(2026, 1, 1),
98    date(2026, 1, 6),
99    date(2026, 4, 3),
100    date(2026, 4, 5),
101    date(2026, 4, 6),
102    date(2026, 5, 1),
103    date(2026, 5, 14),
104    date(2026, 5, 24),
105    date(2026, 6, 6),
106    date(2026, 6, 20),
107    date(2026, 10, 31),
108    date(2026, 12, 24),
109    date(2026, 12, 25),
110    date(2026, 12, 26),
111    date(2026, 12, 31),
112    date(2027, 1, 1),
113    date(2027, 1, 6),
114    date(2027, 3, 26),
115    date(2027, 3, 28),
116    date(2027, 3, 29),
117    date(2027, 5, 1),
118    date(2027, 5, 6),
119    date(2027, 5, 16),
120    date(2027, 6, 6),
121    date(2027, 6, 26),
122    date(2027, 11, 6),
123    date(2027, 12, 24),
124    date(2027, 12, 25),
125    date(2027, 12, 26),
126    date(2027, 12, 31),
127    date(2028, 1, 1),
128    date(2028, 1, 6),
129    date(2028, 4, 14),
130    date(2028, 4, 16),
131    date(2028, 4, 17),
132    date(2028, 5, 1),
133    date(2028, 5, 25),
134    date(2028, 6, 4),
135    date(2028, 6, 6),
136    date(2028, 6, 24),
137    date(2028, 11, 4),
138    date(2028, 12, 24),
139    date(2028, 12, 25),
140    date(2028, 12, 26),
141    date(2028, 12, 31),
142];