use rust_decimal::Decimal;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize)]
pub enum Netzebene {
Hoechstspannung,
UmspannungHoechstHoch,
Hochspannung,
UmspannungHochMittel,
Mittelspannung,
UmspannungMittelNieder,
Niederspannung,
}
impl Netzebene {
#[must_use]
pub const fn label(self) -> &'static str {
match self {
Self::Hoechstspannung => "Höchstspannung",
Self::UmspannungHoechstHoch => "Umspannung HöS/HS",
Self::Hochspannung => "Hochspannung",
Self::UmspannungHochMittel => "Umspannung HS/MS",
Self::Mittelspannung => "Mittelspannung",
Self::UmspannungMittelNieder => "Umspannung MS/NS",
Self::Niederspannung => "Niederspannung",
}
}
#[must_use]
pub const fn ist_umspannung(self) -> bool {
matches!(
self,
Self::UmspannungHoechstHoch | Self::UmspannungHochMittel | Self::UmspannungMittelNieder
)
}
}
pub const ARBEITSPREIS_NUR_GRENZE_KWH: Decimal = rust_decimal::dec!(100_000);
#[must_use]
pub fn benutzungsstundenzahl(
jahresarbeit_kwh: Decimal,
jahreshoechstleistung_kw: Decimal,
) -> Option<Decimal> {
if jahreshoechstleistung_kw.is_zero() {
return None;
}
Some((jahresarbeit_kwh / jahreshoechstleistung_kw).round_dp(1))
}
#[must_use]
pub fn arbeitspreis_nur_zulaessig(ebene: Netzebene, jahresarbeit_kwh: Decimal) -> bool {
ebene == Netzebene::Niederspannung && jahresarbeit_kwh <= ARBEITSPREIS_NUR_GRENZE_KWH
}
#[cfg(test)]
mod tests {
use super::*;
use rust_decimal::dec;
#[test]
fn benutzungsstunden_is_energy_over_peak() {
assert_eq!(
benutzungsstundenzahl(dec!(1_000_000), dec!(200)),
Some(dec!(5000))
);
assert_eq!(
benutzungsstundenzahl(dec!(876_000), dec!(100)),
Some(dec!(8760))
);
}
#[test]
fn benutzungsstunden_is_undefined_without_a_peak() {
assert_eq!(benutzungsstundenzahl(dec!(1000), Decimal::ZERO), None);
}
#[test]
fn the_arbeitspreis_only_option_needs_both_conditions() {
assert!(arbeitspreis_nur_zulaessig(
Netzebene::Niederspannung,
dec!(3500)
));
assert!(arbeitspreis_nur_zulaessig(
Netzebene::Niederspannung,
dec!(100_000)
));
assert!(
!arbeitspreis_nur_zulaessig(Netzebene::Niederspannung, dec!(100_001)),
"above the threshold"
);
assert!(
!arbeitspreis_nur_zulaessig(Netzebene::Mittelspannung, dec!(3500)),
"the option is Niederspannung only"
);
}
#[test]
fn the_levels_order_and_classify() {
assert!(Netzebene::Hoechstspannung < Netzebene::Niederspannung);
assert!(Netzebene::UmspannungHochMittel.ist_umspannung());
assert!(!Netzebene::Mittelspannung.ist_umspannung());
assert_eq!(
Netzebene::UmspannungMittelNieder.label(),
"Umspannung MS/NS"
);
}
}