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 get_by_vat_id(country: Country, vat_id: &str) -> Option<&'static Self> {
85 match country {
86 Country::SE => sweden::GRID_OPERATORS
87 .iter()
88 .find(|o| o.vat_number == vat_id)
89 .copied(),
90 }
91 }
92
93 pub fn all() -> Vec<&'static Self> {
94 sweden::GRID_OPERATORS.to_vec()
95 }
96
97 pub fn all_for_country(country: Country) -> &'static [&'static Self] {
98 match country {
99 Country::SE => sweden::GRID_OPERATORS,
100 }
101 }
102
103 pub(crate) const fn builder() -> GridOperatorBuilder {
104 GridOperatorBuilder::new()
105 }
106
107 pub fn simplified(
108 &self,
109 fuse_size: u16,
110 yearly_consumption: u32,
111 language: Language,
112 ) -> GridOperatorSimplified {
113 GridOperatorSimplified::new(self, fuse_size, yearly_consumption, language)
114 }
115}
116
117#[derive(Debug, Clone, Serialize)]
119#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
120pub struct GridOperatorSimplified {
121 name: &'static str,
122 vat_number: &'static str,
123 country: Country,
125 price_lists: Vec<PriceListSimplified>,
126}
127
128impl GridOperatorSimplified {
129 pub fn name(&self) -> &'static str {
130 self.name
131 }
132
133 pub fn vat_number(&self) -> &'static str {
134 self.vat_number
135 }
136
137 pub fn country(&self) -> Country {
138 self.country
139 }
140
141 pub fn price_lists(&self) -> &[PriceListSimplified] {
142 &self.price_lists
143 }
144}
145
146impl GridOperatorSimplified {
147 fn new(op: &GridOperator, fuse_size: u16, yearly_consumption: u32, language: Language) -> Self {
148 Self {
149 name: op.name,
150 vat_number: op.vat_number,
151 country: op.country(),
152 price_lists: op
153 .active_price_lists()
154 .into_iter()
155 .map(|pl| pl.simplified(fuse_size, yearly_consumption, language))
156 .collect(),
157 }
158 }
159}
160
161#[derive(Debug, Clone)]
162pub(crate) struct GridOperatorBuilder {
163 name: Option<&'static str>,
164 vat_number: Option<&'static str>,
165 country: Option<Country>,
167 main_fuses: Option<MainFuseSizes>,
169 price_lists: Option<&'static [PriceList]>,
170 links: Option<Links>,
171}
172
173impl GridOperatorBuilder {
174 pub(crate) const fn new() -> Self {
175 Self {
176 name: None,
177 vat_number: None,
178 country: None,
179 main_fuses: None,
180 price_lists: None,
181 links: None,
182 }
183 }
184
185 pub(crate) const fn name(mut self, name: &'static str) -> Self {
186 self.name = Some(name);
187 self
188 }
189
190 pub(crate) const fn vat_number(mut self, vat_number: &'static str) -> Self {
191 self.vat_number = Some(vat_number);
192 self
193 }
194
195 pub(crate) const fn country(mut self, country: Country) -> Self {
196 self.country = Some(country);
197 self
198 }
199
200 pub(crate) const fn main_fuses(mut self, main_fuses: MainFuseSizes) -> Self {
201 self.main_fuses = Some(main_fuses);
202 self
203 }
204
205 pub(crate) const fn links(mut self, links: Links) -> Self {
206 self.links = Some(links);
207 self
208 }
209
210 pub(crate) const fn price_lists(mut self, price_lists: &'static [PriceList]) -> Self {
211 self.price_lists = Some(price_lists);
212 self
213 }
214
215 pub(crate) const fn build(self) -> GridOperator {
216 GridOperator {
217 name: self.name.expect("`name` required"),
218 vat_number: self.vat_number.expect("`vat_number` required"),
219 country: self.country.expect("`country` required"),
220 main_fuses: self.main_fuses.expect("`main_fuses` required"),
221 price_lists: self.price_lists.expect("`price_lists` expected"),
222 links: self.links.expect("`links` required"),
223 }
224 }
225}