use crate::EntityId;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct HydroStorage {
pub hydro_id: EntityId,
pub value_hm3: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct HydroPastInflows {
pub hydro_id: EntityId,
pub values_m3s: Vec<f64>,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct InitialConditions {
pub storage: Vec<HydroStorage>,
pub filling_storage: Vec<HydroStorage>,
#[cfg_attr(feature = "serde", serde(default))]
pub past_inflows: Vec<HydroPastInflows>,
}
impl Default for InitialConditions {
fn default() -> Self {
Self {
storage: Vec::new(),
filling_storage: Vec::new(),
past_inflows: Vec::new(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_initial_conditions_construction() {
let ic = InitialConditions {
storage: vec![
HydroStorage {
hydro_id: EntityId(0),
value_hm3: 15_000.0,
},
HydroStorage {
hydro_id: EntityId(1),
value_hm3: 8_500.0,
},
],
filling_storage: vec![HydroStorage {
hydro_id: EntityId(10),
value_hm3: 200.0,
}],
past_inflows: vec![HydroPastInflows {
hydro_id: EntityId(0),
values_m3s: vec![600.0, 500.0],
}],
};
assert_eq!(ic.storage.len(), 2);
assert_eq!(ic.filling_storage.len(), 1);
assert_eq!(ic.past_inflows.len(), 1);
assert_eq!(ic.storage[0].hydro_id, EntityId(0));
assert_eq!(ic.storage[0].value_hm3, 15_000.0);
assert_eq!(ic.storage[1].hydro_id, EntityId(1));
assert_eq!(ic.filling_storage[0].hydro_id, EntityId(10));
assert_eq!(ic.filling_storage[0].value_hm3, 200.0);
assert_eq!(ic.past_inflows[0].hydro_id, EntityId(0));
assert_eq!(ic.past_inflows[0].values_m3s, vec![600.0, 500.0]);
}
#[test]
fn test_initial_conditions_default_is_empty() {
let ic = InitialConditions::default();
assert!(ic.storage.is_empty());
assert!(ic.filling_storage.is_empty());
assert!(ic.past_inflows.is_empty());
}
#[test]
fn test_hydro_storage_clone() {
let hs = HydroStorage {
hydro_id: EntityId(5),
value_hm3: 1_234.5,
};
let cloned = hs.clone();
assert_eq!(hs, cloned);
assert_eq!(cloned.hydro_id, EntityId(5));
assert_eq!(cloned.value_hm3, 1_234.5);
}
#[test]
fn test_hydro_past_inflows_clone() {
let hpi = HydroPastInflows {
hydro_id: EntityId(3),
values_m3s: vec![300.0, 200.0, 100.0],
};
let cloned = hpi.clone();
assert_eq!(hpi, cloned);
assert_eq!(cloned.hydro_id, EntityId(3));
assert_eq!(cloned.values_m3s, vec![300.0, 200.0, 100.0]);
}
#[cfg(feature = "serde")]
#[test]
fn test_initial_conditions_serde_roundtrip() {
let ic = InitialConditions {
storage: vec![
HydroStorage {
hydro_id: EntityId(0),
value_hm3: 15_000.0,
},
HydroStorage {
hydro_id: EntityId(1),
value_hm3: 8_500.0,
},
],
filling_storage: vec![HydroStorage {
hydro_id: EntityId(10),
value_hm3: 200.0,
}],
past_inflows: vec![HydroPastInflows {
hydro_id: EntityId(0),
values_m3s: vec![600.0, 500.0],
}],
};
let json = serde_json::to_string(&ic).unwrap();
let deserialized: InitialConditions = serde_json::from_str(&json).unwrap();
assert_eq!(ic, deserialized);
}
#[cfg(feature = "serde")]
#[test]
fn test_initial_conditions_serde_roundtrip_empty_past_inflows() {
let ic = InitialConditions {
storage: vec![HydroStorage {
hydro_id: EntityId(0),
value_hm3: 1_000.0,
}],
filling_storage: vec![],
past_inflows: vec![],
};
let json = serde_json::to_string(&ic).unwrap();
let deserialized: InitialConditions = serde_json::from_str(&json).unwrap();
assert_eq!(ic, deserialized);
assert_eq!(deserialized.past_inflows.len(), 0);
}
}