Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created November 8, 2018 23:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rust-play/8121e31786e415efae55c76c2577d5ec to your computer and use it in GitHub Desktop.
Save rust-play/8121e31786e415efae55c76c2577d5ec to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
#![allow(dead_code, non_snake_case)]
use std::collections::HashSet;
use uuid::Uuid;
type Stamp = String;
type Value = String;
type Item = (Stamp, Value);
#[derive(Debug, Default)]
struct AddOnlySet {
values: HashSet<Item>,
}
fn new_stamp() -> Stamp {
format!("{}", Uuid::new_v4().to_simple())
}
/// Merge to CvRDT
trait Merge {
fn merge(&self, other: &Self) -> Self;
}
/// Syntetize the items (strip the tags)
trait Items {
fn items(&self) -> HashSet<&Value>;
}
impl AddOnlySet {
fn add(&mut self, value: Item) {
self.values.insert(value);
}
}
impl Items for AddOnlySet {
fn items(&self) -> HashSet<&Value> {
self.values.iter().map(|i| &i.1).collect()
}
}
impl Merge for AddOnlySet {
fn merge(&self, other: &Self) -> Self {
let values = self.values.union(&other.values).cloned().collect();
Self { values }
}
}
#[derive(Debug, Default)]
struct ObservedRemoveSet {
added: AddOnlySet,
removed: AddOnlySet,
}
impl Merge for ObservedRemoveSet {
fn merge(&self, other: &Self) -> Self {
let added = self.added.merge(&other.added);
let removed = self.removed.merge(&other.removed);
Self { added, removed }
}
}
impl ObservedRemoveSet {
fn add(&mut self, value: Value) {
let stamp = new_stamp();
self.added.add((stamp, value));
}
fn remove(&mut self, value: Value) {
for (s, v) in self.added.values.iter().cloned() {
if v == value {
self.removed.add((s, v));
}
}
}
}
impl Items for ObservedRemoveSet {
fn items(&self) -> HashSet<&Value> {
self.added
.values
.difference(&self.removed.values)
.map(|i| &i.1)
.collect()
}
}
#[test]
fn test_merge_ObservedRemoveSet() {
let mut set1 = ObservedRemoveSet::default();
set1.add("Pasta".to_string());
set1.add("Pesto".to_string());
let mut set2 = ObservedRemoveSet::default();
set2.remove("Pesto".to_string()); // "Pesto" is not found in set2
let mut set3 = set1.merge(&set2);
assert!(set3.items().len() == 2);
set3.remove("Pesto".to_string()); // but is found in set3
assert!(set3.items().len() == 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment