1use std::fmt;
2
3use crate::{Op, OpPayload};
4
5#[derive(PartialEq, Eq, Clone)]
10pub enum ChronofoldError<A, T> {
11    UnknownReference(Op<A, T>),
12    FutureTimestamp(Op<A, T>),
13    ExistingTimestamp(Op<A, T>),
14}
15
16impl<A, T> fmt::Debug for ChronofoldError<A, T>
17where
18    A: fmt::Debug + fmt::Display + Copy,
19{
20    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21        use ChronofoldError::*;
22        let (name, op) = match self {
23            UnknownReference(op) => ("UnknownReference", op),
24            FutureTimestamp(op) => ("FutureTimestamp", op),
25            ExistingTimestamp(op) => ("ExistingTimestamp", op),
26        };
27        f.debug_tuple(name).field(&op.omit_value()).finish()
28    }
29}
30
31impl<A, T> fmt::Display for ChronofoldError<A, T>
32where
33    A: fmt::Debug + fmt::Display + Copy,
34{
35    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36        use ChronofoldError::*;
37        match self {
38            UnknownReference(op) => write!(
39                f,
40                "unknown reference {}",
41                op.payload
42                    .reference()
43                    .as_ref()
44                    .expect("reference must not be `None`")
45            ),
46            FutureTimestamp(op) => write!(f, "future timestamp {}", op.id),
47            ExistingTimestamp(op) => write!(f, "existing timestamp {}", op.id),
48        }
49    }
50}
51
52impl<A, T> std::error::Error for ChronofoldError<A, T> where A: fmt::Debug + fmt::Display + Copy {}
53
54impl<A, T> Op<A, T>
55where
56    A: Copy,
57{
58    fn omit_value(&self) -> Op<A, Omitted> {
59        use OpPayload::*;
60        Op {
61            id: self.id,
62            payload: match self.payload {
63                Root => Root,
64                Insert(t, _) => Insert(t, Omitted),
65                Delete(t) => Delete(t),
66            },
67        }
68    }
69}
70
71#[derive(Debug)]
72struct Omitted;