~dkellner/chronofold

ref: 447534aa14605bad02b949010da7726420f26a7b chronofold/src/error.rs -rw-r--r-- 1.9 KiB
447534aa — Dominik Kellner Remove obsolete dependency 2 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::fmt;

use crate::{Change, Op, Timestamp};

/// An error occured when applying an op.
///
/// Note that this implements `Debug`, `Display` and `Error` for all types `T`,
/// as the contents of changes are omitted from any output.
#[derive(PartialEq, Eq, Clone)]
pub enum ChronofoldError<A, T> {
    UnknownReference(Op<A, T>),
    ExistingTimestamp(Op<A, T>),
}

impl<A: fmt::Debug + fmt::Display + Copy, T> fmt::Debug for ChronofoldError<A, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use ChronofoldError::*;
        let (name, op) = match self {
            UnknownReference(op) => ("UnknownReference", op),
            ExistingTimestamp(op) => ("ExistingTimestamp", op),
        };
        f.debug_tuple(name).field(&DebugOp::from(op)).finish()
    }
}

impl<A: fmt::Debug + fmt::Display + Copy, T> fmt::Display for ChronofoldError<A, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use ChronofoldError::*;
        match self {
            UnknownReference(op) => write!(
                f,
                "unknown reference {}",
                op.reference.as_ref().expect("reference must not be `None`")
            ),
            ExistingTimestamp(op) => write!(f, "existing timestamp {}", op.id),
        }
    }
}

impl<A: fmt::Debug + fmt::Display + Copy, T> std::error::Error for ChronofoldError<A, T> {}

#[derive(Debug)]
struct DebugOp<A> {
    id: Timestamp<A>,
    reference: Option<Timestamp<A>>,
    change: Change<Omitted>,
}

impl<A: fmt::Debug + fmt::Display + Copy, T> From<&Op<A, T>> for DebugOp<A> {
    fn from(source: &Op<A, T>) -> Self {
        use Change::*;
        Self {
            id: source.id,
            reference: source.reference,
            change: match source.change {
                Insert(_) => Insert(Omitted),
                Delete => Delete,
            },
        }
    }
}

#[derive(Debug)]
struct Omitted;