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];