pub struct Cell<T, Seq> {
sequence: Seq,
value: T,
}
impl<T, SequenceFactory: crate::SequenceFactory> Cell<T, crate::Sequence<SequenceFactory>> {
pub fn new(ctx: &mut crate::Context<SequenceFactory>, value: T) -> Self {
Cell {
sequence: ctx.next_sequence(),
value,
}
}
pub fn set(&mut self, ctx: &mut crate::Context<SequenceFactory>, value: T) {
*self.borrow_mut(ctx) = value;
}
pub fn last_modified(&self) -> &crate::Sequence<SequenceFactory> {
&self.sequence
}
pub fn borrow_mut(&mut self, ctx: &mut crate::Context<SequenceFactory>) -> &mut T {
self.sequence = ctx.next_sequence();
&mut self.value
}
pub fn into(self) -> T {
self.value
}
}
#[derive(Clone,Debug)]
pub struct CellDiff<T, Seq>(Option<Update<T, Seq>>);
#[derive(Clone,Debug)]
struct Update<T, Seq> {
new: Cell<T, Seq>,
old: T,
}
impl<
T: Clone,
SequenceFactory: crate::SequenceFactory,
> crate::Mergable
for Cell<T, crate::Sequence<SequenceFactory>> {
type Diff = CellDiff<T, crate::Sequence<SequenceFactory>>;
type Seq = crate::Sequence<SequenceFactory>;
fn merge(&mut self, other: Self) {
if other.sequence > self.sequence {
*self = other
}
}
fn diff(&self, other: &Self) -> Self::Diff {
CellDiff(if self.sequence > other.sequence {
Some(Update{
new: self.clone(),
old: other.value.clone(),
})
} else {
None
})
}
fn apply(&mut self, diff: Self::Diff) -> Result<(), crate::ApplyError> {
if let Some(diff) = diff.0 {
self.merge(diff.new);
}
Ok(())
}
fn clean(&mut self, _cutoff: &Self::Seq) {
}
}
impl<T, SequenceFactory: crate::SequenceFactory> crate::Diff
for CellDiff<T, crate::Sequence<SequenceFactory>> {
fn is_empty(&self) -> bool {
self.0.is_none()
}
fn revert(mut self) -> Result<Self, crate::RevertError> {
if let Some(ref mut diff) = self.0 {
diff.new.sequence = diff.new.sequence.undo()?;
std::mem::swap(&mut diff.new.value, &mut diff.old);
}
Ok(self)
}
}
impl<T: Clone, SF: Clone> Clone for Cell<T, SF> {
fn clone(&self) -> Self {
Cell {
sequence: self.sequence.clone(),
value: self.value.clone(),
}
}
}
impl<T, SF> std::ops::Deref for Cell<T, SF> {
type Target = T;
fn deref(&self) -> &T {
&self.value
}
}
impl<T: PartialEq, Seq> PartialEq for Cell<T, Seq> {
fn eq(&self, other: &Self) -> bool {
self.value == other.value
}
}
impl<T: std::fmt::Debug, Seq> std::fmt::Debug for Cell<T, Seq> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.value.fmt(f)
}
}
#[test]
fn test_merge() {
let mut ctx = crate::Context::default();
let result = crate::test::test_merge(&mut [
&Cell::new(&mut ctx, "one"),
&Cell::new(&mut ctx, "two"),
&Cell::new(&mut ctx, "six"),
]);
assert_eq!(result.value, "six");
}
#[test]
fn test_update() {
let mut ctx = crate::Context::default();
let initial = Cell::new(&mut ctx, "old");
let mut update = initial.clone();
update.set(&mut ctx, "new");
let result = crate::test::test_merge(&mut [&initial, &update]);
assert_eq!(result.value, "new");
}
#[test]
fn test_revert() {
let mut ctx = crate::Context::default();
let initial = Cell::new(&mut ctx, "old");
let mut update = initial.clone();
update.set(&mut ctx, "new");
let diff = crate::Mergable::diff(&update, &initial);
let revert = crate::Diff::revert(diff).unwrap();
crate::Mergable::apply(&mut update, revert).unwrap();
assert_eq!(update.value, "old");
}
#[test]
fn test_revert_stale() {
let mut ctx = crate::Context::default();
let orig = Cell::new(&mut ctx, "old");
let mut base = orig.clone();
let mut updated = base.clone();
updated.set(&mut ctx, "new");
let diff_new = crate::Mergable::diff(&updated, &base);
crate::Mergable::apply(&mut base, diff_new.clone()).unwrap();
updated.set(&mut ctx, "newer");
let diff_newer = crate::Mergable::diff(&updated, &base);
crate::Mergable::apply(&mut base, diff_newer.clone()).unwrap();
let revert = crate::Diff::revert(diff_new.clone()).unwrap();
let result = crate::test::test_apply(orig, &mut [
diff_new,
diff_newer,
revert,
]);
assert_eq!(result.value, "newer");
}