use serde::{Deserialize, Serialize};
use serde_json::Value;
use std::collections::BTreeMap;
use crate::protocol_machine_runner::ProtocolMachineTraceEvent;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimRunInput {
#[serde(deserialize_with = "crate::schema::deserialize_schema_version")]
pub schema_version: String,
pub scenario: Value,
pub global_type: Value,
pub local_types: BTreeMap<String, Value>,
#[serde(default)]
pub initial_states: BTreeMap<String, Vec<Value>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimRunOutput {
#[serde(deserialize_with = "crate::schema::deserialize_schema_version")]
pub schema_version: String,
#[serde(default)]
pub trace: Vec<ProtocolMachineTraceEvent>,
#[serde(default)]
pub violations: Vec<Value>,
#[serde(default)]
pub artifacts: Value,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SimulationStructuredError {
pub code: String,
#[serde(default)]
pub path: Option<String>,
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SimTraceValidation {
pub valid: bool,
#[serde(default)]
pub errors: Vec<SimulationStructuredError>,
#[serde(default)]
pub artifacts: Value,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn sim_trace_validation_roundtrip() {
let validation = SimTraceValidation {
valid: false,
errors: vec![SimulationStructuredError {
code: "sim.trace.mismatch".to_string(),
path: Some("trace[0]".to_string()),
message: "event mismatch".to_string(),
}],
artifacts: serde_json::json!({"kind": "diff"}),
};
let encoded = serde_json::to_value(&validation).expect("encode");
let decoded: SimTraceValidation = serde_json::from_value(encoded).expect("decode");
assert!(!decoded.valid);
assert_eq!(decoded.errors.len(), 1);
assert_eq!(decoded.errors[0].code, "sim.trace.mismatch");
}
}