Skip to main content

bo4e_core/com/
tariff_price.rs

1//! Tariff price (Tarifpreis) component.
2
3use serde::{Deserialize, Serialize};
4
5use crate::enums::{Currency, PriceType, Unit};
6use crate::traits::{Bo4eMeta, Bo4eObject};
7
8/// A tariff price with its type and value.
9///
10/// German: Tarifpreis
11///
12/// # Example
13///
14/// ```rust
15/// use bo4e_core::com::TariffPrice;
16/// use bo4e_core::enums::{Currency, PriceType, Unit};
17///
18/// let tariff_price = TariffPrice {
19///     price_type: Some(PriceType::WorkingPriceSingleTariff),
20///     value: Some(0.30),
21///     currency: Some(Currency::Eur),
22///     reference_unit: Some(Unit::KilowattHour),
23///     ..Default::default()
24/// };
25/// ```
26#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
27#[cfg_attr(feature = "json-schema", derive(schemars::JsonSchema))]
28#[cfg_attr(feature = "json-schema", schemars(rename = "Tarifpreis"))]
29#[serde(rename_all = "camelCase")]
30pub struct TariffPrice {
31    /// BO4E metadata
32    #[serde(flatten)]
33    pub meta: Bo4eMeta,
34
35    /// Type of tariff price (Preistyp)
36    #[serde(skip_serializing_if = "Option::is_none")]
37    #[cfg_attr(feature = "json-schema", schemars(rename = "preistyp"))]
38    pub price_type: Option<PriceType>,
39
40    /// Price value (Wert)
41    #[serde(skip_serializing_if = "Option::is_none")]
42    #[cfg_attr(feature = "json-schema", schemars(rename = "wert"))]
43    pub value: Option<f64>,
44
45    /// Currency (Waehrung)
46    #[serde(skip_serializing_if = "Option::is_none")]
47    #[cfg_attr(feature = "json-schema", schemars(rename = "waehrung"))]
48    pub currency: Option<Currency>,
49
50    /// Reference unit (Bezugseinheit)
51    #[serde(skip_serializing_if = "Option::is_none")]
52    #[cfg_attr(feature = "json-schema", schemars(rename = "bezugseinheit"))]
53    pub reference_unit: Option<Unit>,
54
55    /// Description (Beschreibung)
56    #[serde(skip_serializing_if = "Option::is_none")]
57    #[cfg_attr(feature = "json-schema", schemars(rename = "beschreibung"))]
58    pub description: Option<String>,
59}
60
61impl Bo4eObject for TariffPrice {
62    fn type_name_german() -> &'static str {
63        "Tarifpreis"
64    }
65
66    fn type_name_english() -> &'static str {
67        "TariffPrice"
68    }
69
70    fn meta(&self) -> &Bo4eMeta {
71        &self.meta
72    }
73
74    fn meta_mut(&mut self) -> &mut Bo4eMeta {
75        &mut self.meta
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82
83    #[test]
84    fn test_work_price() {
85        let price = TariffPrice {
86            price_type: Some(PriceType::WorkingPriceSingleTariff),
87            value: Some(30.5),
88            currency: Some(Currency::Eur),
89            reference_unit: Some(Unit::KilowattHour),
90            ..Default::default()
91        };
92
93        assert_eq!(price.price_type, Some(PriceType::WorkingPriceSingleTariff));
94        assert_eq!(price.value, Some(30.5));
95    }
96
97    #[test]
98    fn test_base_price() {
99        let price = TariffPrice {
100            price_type: Some(PriceType::BasePrice),
101            value: Some(12.50),
102            currency: Some(Currency::Eur),
103            reference_unit: Some(Unit::Month),
104            description: Some("Monthly base fee".to_string()),
105            ..Default::default()
106        };
107
108        assert_eq!(price.price_type, Some(PriceType::BasePrice));
109    }
110
111    #[test]
112    fn test_default() {
113        let price = TariffPrice::default();
114        assert!(price.price_type.is_none());
115        assert!(price.value.is_none());
116    }
117
118    #[test]
119    fn test_roundtrip() {
120        let price = TariffPrice {
121            price_type: Some(PriceType::WorkingPriceSingleTariff),
122            value: Some(25.75),
123            currency: Some(Currency::Eur),
124            reference_unit: Some(Unit::KilowattHour),
125            description: Some("Peak rate".to_string()),
126            ..Default::default()
127        };
128
129        let json = serde_json::to_string(&price).unwrap();
130        let parsed: TariffPrice = serde_json::from_str(&json).unwrap();
131        assert_eq!(price, parsed);
132    }
133
134    #[test]
135    fn test_bo4e_object_impl() {
136        assert_eq!(TariffPrice::type_name_german(), "Tarifpreis");
137        assert_eq!(TariffPrice::type_name_english(), "TariffPrice");
138    }
139}