~dkellner/chronofold

e58b75dac570cddd6ad6b65126bb0633cc41d703 — Dominik Kellner 1 year, 6 months ago 025024f
Add `ChronofoldError::FutureTimestamp`
3 files changed, 23 insertions(+), 0 deletions(-)

M src/error.rs
M src/lib.rs
M tests/errors.rs
M src/error.rs => src/error.rs +3 -0
@@ 9,6 9,7 @@ use crate::{Op, OpPayload};
#[derive(PartialEq, Eq, Clone)]
pub enum ChronofoldError<A, T> {
    UnknownReference(Op<A, T>),
    FutureTimestamp(Op<A, T>),
    ExistingTimestamp(Op<A, T>),
}



@@ 20,6 21,7 @@ where
        use ChronofoldError::*;
        let (name, op) = match self {
            UnknownReference(op) => ("UnknownReference", op),
            FutureTimestamp(op) => ("FutureTimestamp", op),
            ExistingTimestamp(op) => ("ExistingTimestamp", op),
        };
        f.debug_tuple(name).field(&op.omit_value()).finish()


@@ 41,6 43,7 @@ where
                    .as_ref()
                    .expect("reference must not be `None`")
            ),
            FutureTimestamp(op) => write!(f, "future timestamp {}", op.id),
            ExistingTimestamp(op) => write!(f, "existing timestamp {}", op.id),
        }
    }

M src/lib.rs => src/lib.rs +7 -0
@@ 208,6 208,13 @@ impl<A: Author, T> Chronofold<A, T> {
            return Err(ChronofoldError::ExistingTimestamp(op));
        }

        // We rely on indices in timestamps being greater or equal than their
        // indices in every local log. This means we cannot apply an op not
        // matching this constraint, even if we know the reference.
        if op.id.0 .0 > self.log.len() {
            return Err(ChronofoldError::FutureTimestamp(op));
        }

        use OpPayload::*;
        match op.payload {
            Root => {

M tests/errors.rs => tests/errors.rs +13 -0
@@ 11,6 11,19 @@ fn unknown_timestamp() {
}

#[test]
fn future_timestamp() {
    let mut cfold = Chronofold::<u8, char>::default();
    let op = Op::insert(
        Timestamp(LogIndex(9), 1),
        Some(Timestamp(LogIndex(0), 0)),
        '.',
    );
    let err = cfold.apply(op.clone()).unwrap_err();
    assert_eq!(ChronofoldError::FutureTimestamp(op), err);
    assert_eq!("future timestamp <9, 1>", format!("{}", err));
}

#[test]
fn existing_timestamp() {
    // Applying the same op twice results in a
    // `ChronofoldError::ExistingTimestamp`: