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
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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.clone()
	}

	/** Mutably borrow the cell.
	 *
	 * Note that the following lines are equivalent. The benefit of `borrow_mut()` is for values that are not (cheaply) clonable.
	 *
	 * ```
	 * # let mut ctx = crate::Context::default();
	 * # let mut ctx = Cell::new(&mut ctx, 0);
	 * *cell.borrow_mut(ctx) += 1;
	 * cell.set(ctx, cell.clone() + 1);
	 * ```
	 */
	pub fn borrow_mut(&mut self, ctx: &mut crate::Context<SequenceFactory>) -> &mut T {
		self.sequence = ctx.next_sequence();
		&mut self.value
	}
}

impl<T: Clone, Seq: PartialOrd + Clone> crate::Mergable for Cell<T, Seq> {
	type Diff = crate::Opaque<Self>;

	fn merge(&mut self, other: Self) {
		if other.sequence > self.sequence {
			*self = other
		}

		// TODO: If the sequences are equal the values *must* be identical. It would be nice to add an assert but I don't want to force `T: PartialEq`.
	}

	fn diff(&self, other: &Self) -> Self::Diff {
		crate::Opaque(if self.sequence > other.sequence {
			self.clone()
		} else {
			other.clone()
		})
	}

	fn apply(&mut self, other: Self::Diff) -> Result<(), crate::ApplyError> {
		self.merge(other.0);

		Ok(())
	}
}

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 result = crate::test::test_merge(&mut [
		Cell{sequence: 1, value: "one"},
		Cell{sequence: 2, value: "two"},
		Cell{sequence: 6, value: "six"},
	]);
	assert_eq!(result.value, "six");
	assert_eq!(result.sequence, 6);
}

#[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");
}