Created
November 8, 2018 23:30
-
-
Save rust-play/8121e31786e415efae55c76c2577d5ec to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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