deltoid/
error.rs

1//!
2
3use 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}