hydra_engine_wds/analysis/
artifact.rs1use crate::io::analysis_io::AnalysisArtifact;
2
3#[derive(Debug)]
5pub enum AnalysisBytesError {
6 Json(serde_json::Error),
8}
9
10impl std::fmt::Display for AnalysisBytesError {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 match self {
13 Self::Json(e) => write!(f, "analysis artifact JSON error: {e}"),
14 }
15 }
16}
17
18impl std::error::Error for AnalysisBytesError {}
19
20impl From<serde_json::Error> for AnalysisBytesError {
21 fn from(value: serde_json::Error) -> Self {
22 Self::Json(value)
23 }
24}
25
26pub fn encode_analysis_artifact(
36 artifact: &AnalysisArtifact,
37) -> Result<Vec<u8>, AnalysisBytesError> {
38 Ok(serde_json::to_vec_pretty(artifact)?)
39}
40
41pub fn decode_analysis_artifact(bytes: &[u8]) -> Result<AnalysisArtifact, AnalysisBytesError> {
43 Ok(serde_json::from_slice(bytes)?)
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use crate::io::analysis_io::{
50 AnalysisArtifact, AnalysisSource, ContinuousDistribution, DistributionSet, HistogramBin,
51 StatusDistribution, SummaryStats, ANALYSIS_SCHEMA_VERSION,
52 };
53
54 #[test]
55 fn round_trip_analysis_bytes() {
56 let artifact = AnalysisArtifact {
57 schema_version: ANALYSIS_SCHEMA_VERSION,
58 source: AnalysisSource {
59 output_file: "network.out".to_string(),
60 report_file: "report.json".to_string(),
61 period_count: 25,
62 },
63 distributions: DistributionSet {
64 pressure: ContinuousDistribution {
65 bins: vec![HistogramBin {
66 start: 0.0,
67 end: 10.0,
68 count: 3,
69 }],
70 summary: SummaryStats {
71 min: 0.0,
72 max: 10.0,
73 mean: 4.0,
74 p05: 0.5,
75 p25: 2.0,
76 p50: 4.0,
77 p75: 6.0,
78 p95: 9.5,
79 },
80 thresholds: None,
81 },
82 head: ContinuousDistribution::default(),
83 flow: ContinuousDistribution::default(),
84 velocity: ContinuousDistribution::default(),
85 status: StatusDistribution {
86 open: 10,
87 closed: 2,
88 active: 1,
89 other: 0,
90 },
91 },
92 demand_reliability: None,
93 service_compliance: None,
94 };
95
96 let bytes = encode_analysis_artifact(&artifact).expect("encode artifact");
97 let decoded = decode_analysis_artifact(&bytes).expect("decode artifact");
98
99 assert_eq!(decoded.schema_version, ANALYSIS_SCHEMA_VERSION);
100 assert_eq!(decoded.source.period_count, 25);
101 assert_eq!(decoded.distributions.pressure.bins.len(), 1);
102 assert_eq!(decoded.distributions.status.open, 10);
103 }
104}