1use crate::{Core, Apply, Delta, FromDelta, IntoDelta};
4use serde_derive::{Deserialize, Serialize};
5use std::sync::TryLockError;
6
7
8#[macro_export]
9macro_rules! ensure_eq {
10 ($left:expr, $right:expr) => {{
11 let (lstr, rstr) = (stringify!($left), stringify!($right));
12 ensure!(
13 $left == $right,
14 "violation: {} == {}\n{} == {}\n{} == {}",
15 lstr, rstr,
16 lstr, $left,
17 rstr, $right
18 )
19 }};
20}
21
22#[macro_export]
23macro_rules! ensure_ne {
24 ($left:expr, $right:expr) => {{
25 let (lstr, rstr) = (stringify!($left), stringify!($right));
26 ensure!(
27 $left != $right,
28 "violation: {} != {}\n{} == {}\n{} == {}",
29 lstr, rstr,
30 lstr, $left,
31 rstr, $right
32 )
33 }};
34}
35
36#[macro_export]
37macro_rules! ensure_gt {
38 ($left:expr, $right:expr) => {{
39 let (lstr, rstr) = (stringify!($left), stringify!($right));
40 ensure!(
41 $left > $right,
42 "violation: {} > {}\n{} == {}\n{} == {}",
43 lstr, rstr,
44 lstr, $left,
45 rstr, $right
46 )
47 }};
48}
49
50#[macro_export]
51macro_rules! ensure_lt {
52 ($left:expr, $right:expr) => {{
53 let (lstr, rstr) = (stringify!($left), stringify!($right));
54 ensure!(
55 $left < $right,
56 "violation: {} < {}\n{} == {}\n{} == {}",
57 lstr, rstr,
58 lstr, $left,
59 rstr, $right
60 )
61 }};
62}
63
64#[macro_export]
65macro_rules! ensure_ge {
66 ($left:expr, $right:expr) => {{
67 let (lstr, rstr) = (stringify!($left), stringify!($right));
68 ensure!(
69 $left >= $right,
70 "violation: {} >= {}\n{} == {}\n{} == {}",
71 lstr, rstr,
72 lstr, $left,
73 rstr, $right
74 )
75 }};
76}
77
78#[macro_export]
79macro_rules! ensure_le {
80 ($left:expr, $right:expr) => {{
81 let (lstr, rstr) = (stringify!($left), stringify!($right));
82 ensure!(
83 $left <= $right,
84 "violation: {} <= {}\n{} == {}\n{} == {}",
85 lstr, rstr,
86 lstr, $left,
87 rstr, $right
88 )
89 }};
90}
91
92#[macro_export]
93macro_rules! ensure {
94 ($predicate:expr $(, $fmt:expr $(, $args:expr)*)? ) => {
95 if $predicate {
96 $crate::error::DeltaResult::Ok(())
97 } else {
98 Err($crate::error::DeltaError::FailedToEnsure {
99 predicate: stringify!($predicate).to_string(),
100 msg: {
101 #[allow(unused)] let mut msg = String::new();
102 $( msg = format!($fmt $(, $args)*); )?
103 msg
104 },
105 file: file!().to_string(),
106 line: line!(),
107 column: column!(),
108 })
109 }
110 };
111}
112
113#[macro_export]
114macro_rules! bug_detected {
115 ($($fmt:expr $(, $args:expr)*)?) => {
116 Err($crate::error::DeltaError::BugDetected {
117 msg: { #[allow(redundant_semicolons)] {
118 #[allow(unused)] let mut msg = String::new();
119 $( msg = format!($fmt $(, $args)*); )? ;
120 msg
121 }},
122 file: file!().to_string(),
123 line: line!(),
124 column: column!(),
125 })
126 };
127}
128
129#[macro_export]
130macro_rules! ExpectedValue {
131 ($name:expr) => {
132 $crate::error::DeltaError::ExpectedValue {
133 type_name: $name.to_string(),
134 file: file!().to_string(),
135 line: line!(),
136 column: column!(),
137 }
138 };
139}
140
141
142
143pub type DeltaResult<T> = Result<T, DeltaError>;
144
145#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
146#[derive(Deserialize, Serialize)]
147pub enum DeltaError {
148 BugDetected {
149 msg: String,
150 file: String,
151 line: u32,
152 column: u32
153 },
154 ExpectedValue {
155 type_name: String,
156 file: String,
157 line: u32,
158 column: u32
159 },
160 FailedToEnsure {
161 predicate: String,
162 msg: String,
163 file: String,
164 line: u32,
165 column: u32,
166 },
167 FailedToApplyDelta { reason: String },
168 FailedToConvertFromDelta { reason: String },
169 IllegalDelta { index: usize },
170 RwLockAccessWouldBlock,
171 RwLockPoisoned(String)
172}
173
174impl<T> From<TryLockError<T>> for DeltaError {
175 fn from(err: TryLockError<T>) -> DeltaError {
176 match err {
177 TryLockError::WouldBlock =>
178 DeltaError::RwLockAccessWouldBlock,
179 TryLockError::Poisoned(psn_err) =>
180 DeltaError::RwLockPoisoned(format!("{}", psn_err)),
181 }
182 }
183}
184
185
186#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
187pub struct DeltaErrorDelta(Option<DeltaError>);
188
189impl Core for DeltaError {
190 type Delta = DeltaErrorDelta;
191}
192
193impl Apply for DeltaError {
194 fn apply(&self, delta: Self::Delta) -> DeltaResult<Self> {
195 match delta {
196 DeltaErrorDelta(Some(derr)) => Ok(derr),
197 DeltaErrorDelta(None) => Ok(self.clone()),
198 }
199 }
200}
201
202impl Delta for DeltaError {
203 fn delta(&self, rhs: &Self) -> DeltaResult<Self::Delta> {
204 Ok(DeltaErrorDelta(Some(rhs.clone())))
205 }
206}
207
208impl FromDelta for DeltaError {
209 fn from_delta(delta: Self::Delta) -> DeltaResult<Self> {
210 match delta {
211 DeltaErrorDelta(Some(derr)) => Ok(derr),
212 DeltaErrorDelta(None) => Err(DeltaError::FailedToConvertFromDelta {
213 reason: format!("Got no delta to convert from"),
214 })
215 }
216 }
217}
218
219impl IntoDelta for DeltaError {
220 fn into_delta(self) -> DeltaResult<Self::Delta> {
221 Ok(DeltaErrorDelta(Some(self)))
222 }
223}