use serde::{Deserialize, Serialize};
use crate::traits::CrdtMerge;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LwwRegister<T: Clone> {
value: T,
timestamp: u64,
node: String,
}
impl<T: Clone> LwwRegister<T> {
pub fn new(node: impl Into<String>, value: T, timestamp: u64) -> Self {
Self { value, timestamp, node: node.into() }
}
pub fn value(&self) -> &T {
&self.value
}
pub fn timestamp(&self) -> u64 {
self.timestamp
}
pub fn set(&mut self, value: T, timestamp: u64, node: impl Into<String>) {
if timestamp > self.timestamp {
self.value = value;
self.timestamp = timestamp;
self.node = node.into();
}
}
}
impl<T: Clone> CrdtMerge for LwwRegister<T> {
fn merge(&mut self, other: &Self) {
if other.timestamp > self.timestamp || (other.timestamp == self.timestamp && other.node > self.node) {
*self = other.clone();
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn later_wins() {
let mut a = LwwRegister::new("n1", "alpha", 1);
let b = LwwRegister::new("n2", "beta", 2);
a.merge(&b);
assert_eq!(*a.value(), "beta");
}
}