use crate::io::analysis_io::AnalysisArtifact;
#[derive(Debug)]
pub enum AnalysisBytesError {
Json(serde_json::Error),
}
impl std::fmt::Display for AnalysisBytesError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Json(e) => write!(f, "analysis artifact JSON error: {e}"),
}
}
}
impl std::error::Error for AnalysisBytesError {}
impl From<serde_json::Error> for AnalysisBytesError {
fn from(value: serde_json::Error) -> Self {
Self::Json(value)
}
}
pub fn encode_analysis_artifact(
artifact: &AnalysisArtifact,
) -> Result<Vec<u8>, AnalysisBytesError> {
Ok(serde_json::to_vec_pretty(artifact)?)
}
pub fn decode_analysis_artifact(bytes: &[u8]) -> Result<AnalysisArtifact, AnalysisBytesError> {
Ok(serde_json::from_slice(bytes)?)
}
#[cfg(test)]
mod tests {
use super::*;
use crate::io::analysis_io::{
AnalysisArtifact, AnalysisSource, ContinuousDistribution, DistributionSet, HistogramBin,
StatusDistribution, SummaryStats, ANALYSIS_SCHEMA_VERSION,
};
#[test]
fn round_trip_analysis_bytes() {
let artifact = AnalysisArtifact {
schema_version: ANALYSIS_SCHEMA_VERSION,
source: AnalysisSource {
output_file: "network.out".to_string(),
report_file: "report.json".to_string(),
period_count: 25,
},
distributions: DistributionSet {
pressure: ContinuousDistribution {
bins: vec![HistogramBin {
start: 0.0,
end: 10.0,
count: 3,
}],
summary: SummaryStats {
min: 0.0,
max: 10.0,
mean: 4.0,
p05: 0.5,
p25: 2.0,
p50: 4.0,
p75: 6.0,
p95: 9.5,
},
thresholds: None,
},
head: ContinuousDistribution::default(),
flow: ContinuousDistribution::default(),
velocity: ContinuousDistribution::default(),
status: StatusDistribution {
open: 10,
closed: 2,
active: 1,
other: 0,
},
},
demand_reliability: None,
service_compliance: None,
};
let bytes = encode_analysis_artifact(&artifact).expect("encode artifact");
let decoded = decode_analysis_artifact(&bytes).expect("decode artifact");
assert_eq!(decoded.schema_version, ANALYSIS_SCHEMA_VERSION);
assert_eq!(decoded.source.period_count, 25);
assert_eq!(decoded.distributions.pressure.bins.len(), 1);
assert_eq!(decoded.distributions.status.open, 10);
}
}