use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct DifferentialReport {
pub property: Property,
pub scenario: Scenario,
pub verdict: Verdict,
pub relation: Relation,
pub finding: Finding,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Property {
pub canon_id: String,
pub statement: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub spec_source: Option<SourceRef>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub impl_source: Option<SourceRef>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct SourceRef {
pub path: String,
pub line: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub snippet: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Scenario {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub fault: Option<FaultSpec>,
#[serde(default)]
pub op_trace: Vec<OpEvent>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub call_path: Vec<CallFrame>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub test_shape: Vec<TestStep>,
pub seed: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub shrink: Option<ShrinkStats>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct FaultSpec {
pub kind: String,
pub op: String,
pub nth: u64,
pub error: String,
pub fired_count: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct OpEvent {
pub seq: u64,
pub op: String,
pub detail: String,
pub injected: bool,
pub result: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct TestStep {
pub label: String,
#[serde(default)]
pub faulted: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct CallFrame {
pub label: String,
pub depth: u32,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub file: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub line: Option<u32>,
pub role: FrameRole,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub io_seq: Option<u64>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
pub enum FrameRole {
#[default]
Normal,
Fault,
Effect,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ShrinkStats {
pub from: u64,
pub to: u64,
pub steps: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Verdict {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cr_id: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub expected_to_fail: Option<ExpectedToFail>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct ExpectedToFail {
pub tag: String,
pub reason: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Relation {
pub kind: String,
pub description: String,
pub compared: Vec<String>,
pub ignored: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum Finding {
StateEq {
expected: Snapshot,
actual: Snapshot,
divergence: Vec<FieldDivergence>,
},
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct Snapshot {
pub label: String,
pub fields: Vec<NamedField>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct NamedField {
pub field: String,
pub value: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub provenance: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct FieldDivergence {
pub field: String,
pub expected: String,
pub actual: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub provenance: Option<String>,
}