use std::collections::HashMap;
use rubo4e::current::PreisblattNetznutzung;
pub trait PreisblattStore {
fn get(&self, nb_mp_id: &str, billing_date: time::Date) -> Option<&PreisblattNetznutzung>;
fn has_preisblatt_for(&self, nb_mp_id: &str) -> bool {
self.get(nb_mp_id, time::macros::date!(9999 - 12 - 31))
.is_some()
}
}
#[derive(Debug, Default)]
pub struct InMemoryPreisblattStore {
inner: HashMap<String, Vec<PreisblattNetznutzung>>,
}
impl InMemoryPreisblattStore {
#[must_use]
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
pub fn insert(&mut self, nb_mp_id: String, sheet: PreisblattNetznutzung) {
self.inner.entry(nb_mp_id).or_default().push(sheet);
}
pub fn sort(&mut self) {
for sheets in self.inner.values_mut() {
sheets.sort_by(|a, b| {
let (a_start, _) = a.validity();
let (b_start, _) = b.validity();
b_start.cmp(&a_start)
});
}
}
}
impl PreisblattStore for InMemoryPreisblattStore {
fn get(&self, nb_mp_id: &str, billing_date: time::Date) -> Option<&PreisblattNetznutzung> {
let sheets = self.inner.get(nb_mp_id)?;
sheets.iter().find(|s| sheet_is_valid(s, billing_date))
}
}
fn sheet_is_valid(sheet: &PreisblattNetznutzung, billing_date: time::Date) -> bool {
match sheet.validity() {
(None, None) => true,
(Some(start), None) => billing_date >= start,
(None, Some(end)) => billing_date <= end,
(Some(start), Some(end)) => billing_date >= start && billing_date <= end,
}
}
#[cfg(test)]
mod tests {
use rubo4e::current::{PreisblattNetznutzung, Zeitraum};
use time::macros::date;
use super::*;
fn make_sheet(start: Option<time::Date>, end: Option<time::Date>) -> PreisblattNetznutzung {
let gueltigkeit = if start.is_some() || end.is_some() {
Some(Zeitraum {
startdatum: start,
enddatum: end,
..Default::default()
})
} else {
None
};
PreisblattNetznutzung {
gueltigkeit,
..Default::default()
}
}
#[test]
fn test_store_get_finds_valid_sheet() {
let mut store = InMemoryPreisblattStore::new();
let sheet = make_sheet(Some(date!(2025 - 01 - 01)), Some(date!(2026 - 01 - 01)));
store.insert("9900000000001".to_owned(), sheet);
assert!(store.get("9900000000001", date!(2025 - 06 - 01)).is_some());
assert!(store.get("9900000000001", date!(2024 - 12 - 31)).is_none());
assert!(store.get("9900000000001", date!(2026 - 01 - 01)).is_some());
assert!(store.get("9900000000001", date!(2026 - 01 - 02)).is_none());
assert!(store.get("9900000000999", date!(2025 - 06 - 01)).is_none()); }
#[test]
fn test_store_open_ended_sheet() {
let mut store = InMemoryPreisblattStore::new();
let sheet = make_sheet(Some(date!(2025 - 01 - 01)), None);
store.insert("9900000000002".to_owned(), sheet);
assert!(store.get("9900000000002", date!(2099 - 12 - 30)).is_some());
}
#[test]
fn test_has_preisblatt_for() {
let mut store = InMemoryPreisblattStore::new();
let sheet = make_sheet(None, None);
store.insert("9900000000003".to_owned(), sheet);
assert!(store.has_preisblatt_for("9900000000003"));
assert!(!store.has_preisblatt_for("9900000000999"));
}
}