1use core::convert::Infallible;
4use core::fmt;
5use core::iter::FromIterator;
6use core::ops::Bound::*;
7use std::collections::BTreeSet;
8
9use serde::{Deserialize, Serialize};
10
11use crate::{CmRDT, CvRDT, Identifier};
12
13#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
15pub enum Op<T> {
16 Insert {
18 id: Identifier<T>,
20 },
21}
22
23#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
28pub struct GList<T: Ord> {
29 list: BTreeSet<Identifier<T>>,
30}
31
32impl<T: fmt::Display + Ord> fmt::Display for GList<T> {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 write!(f, "GList[")?;
35 let mut iter = self.list.iter();
36 if let Some(e) = iter.next() {
37 write!(f, "{}", e)?;
38 }
39 for e in iter {
40 write!(f, "{}", e)?;
41 }
42 write!(f, "]")
43 }
44}
45
46impl<T: Ord> Default for GList<T> {
47 fn default() -> Self {
48 Self {
49 list: Default::default(),
50 }
51 }
52}
53
54impl<T: Ord + Clone> GList<T> {
55 pub fn new() -> Self {
57 Self::default()
58 }
59
60 pub fn read<'a, C: FromIterator<&'a T>>(&'a self) -> C {
62 self.list.iter().map(|id| id.value()).collect()
63 }
64
65 pub fn read_into<C: FromIterator<T>>(self) -> C {
67 self.list.into_iter().map(|id| id.into_value()).collect()
68 }
69
70 pub fn iter(&self) -> std::collections::btree_set::Iter<Identifier<T>> {
72 self.list.iter()
73 }
74
75 pub fn get(&self, idx: usize) -> Option<&Identifier<T>> {
77 self.list.iter().nth(idx)
78 }
79
80 pub fn insert_before(&self, high_id_opt: Option<&Identifier<T>>, elem: T) -> Op<T> {
82 let low_id_opt = high_id_opt.and_then(|high_id| {
83 self.list
84 .range((Unbounded, Excluded(high_id.clone())))
85 .rev()
86 .find(|id| id < &high_id)
87 });
88 let id = Identifier::between(low_id_opt, high_id_opt, elem);
89 Op::Insert { id }
90 }
91
92 pub fn insert_after(&self, low_id_opt: Option<&Identifier<T>>, elem: T) -> Op<T> {
94 let high_id_opt = low_id_opt.and_then(|low_id| {
95 self.list
96 .range((Excluded(low_id.clone()), Unbounded))
97 .find(|id| id > &low_id)
98 });
99 let id = Identifier::between(low_id_opt, high_id_opt, elem);
100 Op::Insert { id }
101 }
102
103 pub fn len(&self) -> usize {
105 self.list.len()
106 }
107
108 pub fn is_empty(&self) -> bool {
110 self.list.is_empty()
111 }
112
113 pub fn first(&self) -> Option<&Identifier<T>> {
115 self.iter().next()
116 }
117
118 pub fn last(&self) -> Option<&Identifier<T>> {
120 self.iter().next_back()
121 }
122}
123
124impl<T: Ord> CmRDT for GList<T> {
125 type Op = Op<T>;
126 type Validation = Infallible;
127
128 fn validate_op(&self, _: &Self::Op) -> Result<(), Self::Validation> {
129 Ok(())
130 }
131
132 fn apply(&mut self, op: Self::Op) {
133 match op {
134 Op::Insert { id } => self.list.insert(id),
135 };
136 }
137}
138
139impl<T: Ord> CvRDT for GList<T> {
140 type Validation = Infallible;
141
142 fn validate_merge(&self, _: &Self) -> Result<(), Self::Validation> {
143 Ok(())
144 }
145
146 fn merge(&mut self, other: Self) {
147 self.list.extend(other.list)
148 }
149}
150
151#[cfg(feature = "quickcheck")]
152use quickcheck::{Arbitrary, Gen};
153
154#[cfg(feature = "quickcheck")]
155impl<T: Arbitrary> Arbitrary for Op<T> {
156 fn arbitrary(g: &mut Gen) -> Self {
157 let id = Identifier::arbitrary(g);
158 Op::Insert { id }
159 }
160}