1use core::fmt;
2
3use serde::Serialize;
4
5use crate::trace::Source;
6
7#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
9pub enum TraceDifference {
10 Status(StatusDiff),
12 Knowledges(KnowledgeDiff),
14 Claims(ClaimDiff),
16 SecurityClaim(SecurityClaimDiff),
18}
19
20impl fmt::Display for TraceDifference {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 match self {
23 TraceDifference::Status(diff) => writeln!(f, "Execution status difference\n{}", diff),
24 TraceDifference::Knowledges(diff) => {
25 writeln!(f, "Differences in knowledges: {}", diff)
26 }
27 TraceDifference::Claims(diff) => write!(f, "{diff}"),
28 TraceDifference::SecurityClaim(diff) => write!(f, "{diff}"),
29 }
30 }
31}
32
33#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
34pub struct StatusDiff {
35 pub first_executed_steps: usize,
36 pub first_status: String,
37 pub second_executed_steps: usize,
38 pub second_status: String,
39 pub total_step: usize,
41}
42
43impl StatusDiff {
44 pub fn as_trace_difference(self) -> TraceDifference {
45 TraceDifference::Status(self)
46 }
47}
48
49impl fmt::Display for StatusDiff {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 writeln!(
52 f,
53 "\tfirst put : (step {}/{}) {}\n\tsecond put : (step {}/{}) {}",
54 self.first_executed_steps,
55 self.total_step,
56 self.first_status,
57 self.second_executed_steps,
58 self.total_step,
59 self.second_status
60 )
61 }
62}
63
64#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
65pub enum KnowledgeDiff {
66 DifferentTypes {
68 index: usize,
69 first_type: String,
70 second_type: String,
71 first_source: Source,
72 second_source: Source,
73 },
74 InnerDifference {
76 index: usize,
77 type_name: String,
78 diff: String,
80 source: Source,
81 },
82}
83
84impl fmt::Display for KnowledgeDiff {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 match self {
87 KnowledgeDiff::DifferentTypes {
88 index,
89 first_type,
90 second_type,
91 first_source,
92 second_source,
93 } => writeln!(
94 f,
95 "knowledge[{}]: {} ({}) != {} ({})",
96 index, first_type, first_source, second_type, second_source
97 ),
98 KnowledgeDiff::InnerDifference {
99 index,
100 type_name,
101 diff,
102 source,
103 } => writeln!(
104 f,
105 "knowledge[{}] ({}, {}) : \n{}",
106 index, type_name, source, diff
107 ),
108 }
109 }
110}
111
112#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
113pub enum ClaimDiff {
114 DifferentTypes {
115 agent: u8,
116 index: usize,
117 first_type: String,
118 second_type: String,
119 },
120 InnerDifference {
121 agent: u8,
122 index: usize,
123 diff: String,
124 },
125}
126
127impl fmt::Display for ClaimDiff {
128 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
129 match self {
130 ClaimDiff::DifferentTypes {
131 index,
132 first_type,
133 second_type,
134 agent,
135 } => {
136 writeln!(
137 f,
138 "Claim [agent{agent},{}]: {} != {}",
139 index, first_type, second_type
140 )
141 }
142 ClaimDiff::InnerDifference { index, diff, agent } => {
143 writeln!(f, "Claim [agent{agent},{}]:\n{}", index, diff)
144 }
145 }
146 }
147}
148
149#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)]
150pub enum SecurityClaimDiff {
151 Different {
152 put: u8,
153 claim: String,
154 },
155 BothError {
156 first_put: String,
157 second_put: String,
158 },
159}
160
161impl SecurityClaimDiff {
162 pub fn as_trace_difference(self) -> TraceDifference {
163 TraceDifference::SecurityClaim(self)
164 }
165}
166
167impl fmt::Display for SecurityClaimDiff {
168 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
169 match self {
170 SecurityClaimDiff::Different { put, claim } => {
171 writeln!(f, "Security Claim violation on PUT {} : \"{}\"", put, claim)
172 }
173 SecurityClaimDiff::BothError {
174 first_put,
175 second_put,
176 } => writeln!(
177 f,
178 "Security Claim violation on both PUT : \"{}\" and \"{}\"",
179 first_put, second_put
180 ),
181 }
182 }
183}