1use chrono::Utc;
2use indexmap::IndexMap;
3use serde::Serialize;
4
5use crate::{
6 Country, Currency, Language, Links, MainFuseSizes, PriceList, price_list::PriceListSimplified,
7 registry::sweden,
8};
9
10#[derive(Debug, Clone, Serialize)]
11#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
12pub struct GridOperator {
13 name: &'static str,
14 vat_number: &'static str,
15 country: Country,
17 main_fuses: MainFuseSizes,
19 price_lists: &'static [PriceList],
20 links: Links,
21}
22
23impl GridOperator {
24 pub const fn name(&self) -> &str {
25 self.name
26 }
27
28 pub const fn vat_number(&self) -> &str {
29 self.vat_number
30 }
31
32 pub const fn country(&self) -> Country {
33 self.country
34 }
35
36 pub const fn links(&self) -> &Links {
37 &self.links
38 }
39
40 pub fn active_price_lists(&self) -> Vec<&'static PriceList> {
41 let now = Utc::now().date_naive();
42 let mut map: IndexMap<Option<&str>, &PriceList> = IndexMap::new();
43 for pl in self.price_lists {
44 if now >= pl.from_date() {
45 if let Some(current_max_date) = map.get(&pl.variant()).map(|pl| pl.from_date()) {
46 if pl.from_date() > current_max_date {
47 map.insert(pl.variant(), pl);
48 }
49 } else {
50 map.insert(pl.variant(), pl);
51 }
52 }
53 }
54 map.into_values().collect()
55 }
56
57 pub fn active_price_list(&self, variant: Option<&str>) -> Option<&'static PriceList> {
58 self.active_price_lists()
59 .iter()
60 .filter(|pl| pl.variant() == variant)
61 .next_back()
62 .copied()
63 }
64
65 pub fn price_lists(&self) -> &'static [PriceList] {
66 self.price_lists
67 }
68
69 pub const fn currency(&self) -> Currency {
70 match self.country {
71 Country::SE => Currency::SEK,
72 }
73 }
74
75 pub fn get(country: Country, name: &str) -> Option<&'static Self> {
76 match country {
77 Country::SE => sweden::GRID_OPERATORS
78 .iter()
79 .find(|o| o.name == name)
80 .copied(),
81 }
82 }
83
84 pub fn all() -> Vec<&'static Self> {
85 sweden::GRID_OPERATORS.to_vec()
86 }
87
88 pub fn all_for_country(country: Country) -> &'static [&'static Self] {
89 match country {
90 Country::SE => sweden::GRID_OPERATORS,
91 }
92 }
93
94 pub(crate) const fn builder() -> GridOperatorBuilder {
95 GridOperatorBuilder::new()
96 }
97
98 pub fn simplified(
99 &self,
100 fuse_size: u16,
101 yearly_consumption: u32,
102 language: Language,
103 ) -> GridOperatorSimplified {
104 GridOperatorSimplified::new(self, fuse_size, yearly_consumption, language)
105 }
106}
107
108#[derive(Debug, Clone, Serialize)]
110#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
111pub struct GridOperatorSimplified {
112 name: &'static str,
113 vat_number: &'static str,
114 country: Country,
116 price_lists: Vec<PriceListSimplified>,
117}
118
119impl GridOperatorSimplified {
120 pub fn name(&self) -> &'static str {
121 self.name
122 }
123
124 pub fn vat_number(&self) -> &'static str {
125 self.vat_number
126 }
127
128 pub fn country(&self) -> Country {
129 self.country
130 }
131
132 pub fn price_lists(&self) -> &[PriceListSimplified] {
133 &self.price_lists
134 }
135}
136
137impl GridOperatorSimplified {
138 fn new(op: &GridOperator, fuse_size: u16, yearly_consumption: u32, language: Language) -> Self {
139 Self {
140 name: op.name,
141 vat_number: op.vat_number,
142 country: op.country(),
143 price_lists: op
144 .active_price_lists()
145 .into_iter()
146 .map(|pl| pl.simplified(fuse_size, yearly_consumption, language))
147 .collect(),
148 }
149 }
150}
151
152#[derive(Debug, Clone)]
153pub(crate) struct GridOperatorBuilder {
154 name: Option<&'static str>,
155 vat_number: Option<&'static str>,
156 country: Option<Country>,
158 main_fuses: Option<MainFuseSizes>,
160 price_lists: Option<&'static [PriceList]>,
161 links: Option<Links>,
162}
163
164impl GridOperatorBuilder {
165 pub(crate) const fn new() -> Self {
166 Self {
167 name: None,
168 vat_number: None,
169 country: None,
170 main_fuses: None,
171 price_lists: None,
172 links: None,
173 }
174 }
175
176 pub(crate) const fn name(mut self, name: &'static str) -> Self {
177 self.name = Some(name);
178 self
179 }
180
181 pub(crate) const fn vat_number(mut self, vat_number: &'static str) -> Self {
182 self.vat_number = Some(vat_number);
183 self
184 }
185
186 pub(crate) const fn country(mut self, country: Country) -> Self {
187 self.country = Some(country);
188 self
189 }
190
191 pub(crate) const fn main_fuses(mut self, main_fuses: MainFuseSizes) -> Self {
192 self.main_fuses = Some(main_fuses);
193 self
194 }
195
196 pub(crate) const fn links(mut self, links: Links) -> Self {
197 self.links = Some(links);
198 self
199 }
200
201 pub(crate) const fn price_lists(mut self, price_lists: &'static [PriceList]) -> Self {
202 self.price_lists = Some(price_lists);
203 self
204 }
205
206 pub(crate) const fn build(self) -> GridOperator {
207 GridOperator {
208 name: self.name.expect("`name` required"),
209 vat_number: self.vat_number.expect("`vat_number` required"),
210 country: self.country.expect("`country` required"),
211 main_fuses: self.main_fuses.expect("`main_fuses` required"),
212 price_lists: self.price_lists.expect("`price_lists` expected"),
213 links: self.links.expect("`links` required"),
214 }
215 }
216}