crdt_sample/
pncounter.rs

1use std::{
2    fmt::Display,
3    iter::Sum,
4    ops::AddAssign,
5    ops::{Add, Sub},
6};
7
8use crate::{GCounter, NodeId};
9
10pub struct PnCounter<V>
11where
12    V: Display
13        + AddAssign
14        + Clone
15        + Copy
16        + for<'v> Sum<&'v V>
17        + Ord
18        + Add<Output = V>
19        + Sub<Output = V>
20        + Default,
21{
22    pub id: NodeId,
23    pub pos_counter: GCounter<V>,
24    pub neg_counter: GCounter<V>,
25    pub default_value: V,
26}
27
28impl<V> PnCounter<V>
29where
30    V: Display
31        + AddAssign
32        + Clone
33        + Copy
34        + for<'v> Sum<&'v V>
35        + Ord
36        + Add<Output = V>
37        + Sub<Output = V>
38        + Default,
39{
40    pub fn new(id: NodeId) -> Self {
41        PnCounter {
42            id: id.clone(),
43            pos_counter: GCounter::new(id.clone()),
44            neg_counter: GCounter::new(id.clone()),
45            default_value: Default::default(),
46        }
47    }
48
49    pub fn inc(&mut self, to_sum: Option<V>) {
50        self.pos_counter.inc(to_sum);
51    }
52
53    pub fn dec(&mut self, to_sub: Option<V>) {
54        self.neg_counter.inc(to_sub);
55    }
56
57    pub fn local(&self) -> V {
58        self.pos_counter.local().clone() - self.neg_counter.local().clone()
59    }
60
61    pub fn read(&self) -> V {
62        self.pos_counter.read() - self.neg_counter.read()
63    }
64
65    pub fn join(&mut self, pncounter: &PnCounter<V>) {
66        self.pos_counter.join(&pncounter.pos_counter);
67        self.neg_counter.join(&pncounter.neg_counter);
68    }
69}