use super::Value;
use crate::{
CausalContext, CausalDotStore, DotStoreJoin, Identifier,
dotstores::recording_sentinel::RecordingSentinel,
sentinel::{DummySentinel, Sentinel},
};
use quickcheck::Gen;
use std::{fmt, ops::RangeBounds};
mod arbitrary_delta_impls;
mod qc_arbitrary_impls;
mod qc_arbitrary_ops;
#[cfg_attr(feature = "arbitrary", allow(dead_code))]
pub(crate) fn join_harness<DS, Init, W1, W2, S, C>(
zero: DS,
init: Init,
w1: W1,
w2: W2,
mut sentinel: S,
check: C,
) where
DS: DotStoreJoin<S> + DotStoreJoin<RecordingSentinel> + Default + Clone,
S: Sentinel,
S::Error: fmt::Debug,
Init: FnOnce(CausalDotStore<DS>, Identifier) -> CausalDotStore<DS>,
W1: FnOnce(&DS, CausalContext, Identifier) -> CausalDotStore<DS>,
W2: FnOnce(&DS, CausalContext, Identifier) -> CausalDotStore<DS>,
C: FnOnce(CausalDotStore<DS>, S),
{
let v = zero;
let init_id = Identifier::new(9, 0);
let v = init(
CausalDotStore {
store: v,
context: CausalContext::new(),
},
init_id,
);
let w1_id = Identifier::new(0, 0);
let mut w1_v = w1(&v.store, v.context.clone(), w1_id);
let w2_id = Identifier::new(1, 0);
let w2_v = w2(&v.store, v.context.clone(), w2_id);
w1_v.test_join_with_and_track(w2_v.store, &w2_v.context, &mut |_| {}, &mut sentinel)
.unwrap();
check(w1_v, sentinel)
}
pub(crate) trait ArbitraryDelta: Sized {
#[cfg(not(feature = "serde"))]
type Delta: Delta<DS = Self>;
#[cfg(feature = "serde")]
type Delta: Delta<DS = Self> + ::serde::Serialize + ::serde::de::DeserializeOwned;
fn arbitrary_delta(
&self,
cc: &CausalContext,
id: Identifier,
keys: &mut KeyTracker,
g: &mut Gen,
depth: usize,
) -> (Self::Delta, CausalDotStore<Self>);
}
pub(crate) trait Delta: Sized + fmt::Display {
type DS: DotStoreJoin<DummySentinel>;
fn depends_on_keyi_in<R: RangeBounds<usize>>(&self, range: R) -> bool;
#[cfg_attr(feature = "arbitrary", allow(dead_code))]
fn into_crdt(
self,
ds: &Self::DS,
cc: &CausalContext,
id: Identifier,
keys: &mut KeyTracker,
) -> CausalDotStore<Self::DS>;
}
pub(crate) use qc_arbitrary_ops::KeyTracker;
#[cfg(test)]
pub(crate) use qc_arbitrary_ops::Ops;