use chrono::NaiveDate;
use crate::EntityId;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PostStudyStage {
pub start_date: NaiveDate,
pub duration_hours: f64,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PostStudyThermalBound {
pub thermal_id: EntityId,
pub post_study_stage_index: usize,
pub cost_per_mwh: f64,
pub min_mw: f64,
pub max_mw: f64,
}
#[derive(Debug, Clone, PartialEq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PostStudyStages {
pub stages: Vec<PostStudyStage>,
pub thermal_bounds: Vec<PostStudyThermalBound>,
}
#[cfg(test)]
mod tests {
use super::*;
fn sample() -> PostStudyStages {
PostStudyStages {
stages: vec![
PostStudyStage {
start_date: NaiveDate::from_ymd_opt(2026, 11, 1)
.unwrap_or_else(|| unreachable!("hardcoded date is valid")),
duration_hours: 720.0,
},
PostStudyStage {
start_date: NaiveDate::from_ymd_opt(2026, 12, 1)
.unwrap_or_else(|| unreachable!("hardcoded date is valid")),
duration_hours: 744.0,
},
],
thermal_bounds: vec![PostStudyThermalBound {
thermal_id: EntityId(86),
post_study_stage_index: 0,
cost_per_mwh: 210.0,
min_mw: 0.0,
max_mw: 350.0,
}],
}
}
#[test]
fn test_construction_and_clone() {
let ps = sample();
assert_eq!(ps.stages.len(), 2);
assert_eq!(ps.thermal_bounds.len(), 1);
assert_eq!(ps.thermal_bounds[0].post_study_stage_index, 0);
assert_eq!(ps.clone(), ps);
}
#[test]
fn test_default_is_empty() {
let ps = PostStudyStages::default();
assert!(ps.stages.is_empty());
assert!(ps.thermal_bounds.is_empty());
}
#[cfg(feature = "serde")]
#[test]
fn test_serde_roundtrip() {
let ps = sample();
let json = serde_json::to_string(&ps).unwrap();
let back: PostStudyStages = serde_json::from_str(&json).unwrap();
assert_eq!(ps, back);
}
#[cfg(feature = "serde")]
#[test]
fn test_postcard_roundtrip() {
let ps = sample();
let bytes = postcard::to_allocvec(&ps).unwrap();
let back: PostStudyStages = postcard::from_bytes(&bytes).unwrap();
assert_eq!(ps, back);
assert_eq!(bytes, postcard::to_allocvec(&back).unwrap());
}
}