1pub mod no_ord;
6pub mod partial_ord;
7
8use std::fmt::Debug;
9
10use serde::{Deserialize, Serialize};
11
12use crate::Access;
13use crate::group::resolver::StrongRemove;
14use crate::group::{GroupAction, GroupControlMessage, GroupCrdt, GroupCrdtState, GroupMember};
15use crate::traits::{IdentityHandle, Operation, OperationId, Orderer};
16
17impl IdentityHandle for char {}
18impl OperationId for u32 {}
19
20pub type MemberId = char;
21pub type MessageId = u32;
22pub type Conditions = ();
23pub type TestResolver = StrongRemove<MemberId, MessageId, Conditions, TestOperation>;
24
25#[derive(Clone, Debug, Deserialize, Serialize)]
26pub struct TestOperation {
27 pub id: u32,
28 pub author: char,
29 pub dependencies: Vec<u32>,
30 pub payload: GroupControlMessage<char, ()>,
31}
32
33impl Operation<char, u32, GroupControlMessage<char, ()>> for TestOperation {
34 fn id(&self) -> u32 {
35 self.id
36 }
37
38 fn author(&self) -> char {
39 self.author
40 }
41
42 fn dependencies(&self) -> Vec<u32> {
43 self.dependencies.clone()
44 }
45
46 fn payload(&self) -> GroupControlMessage<char, ()> {
47 self.payload.clone()
48 }
49}
50
51fn make_group_op(
52 actor_id: MemberId,
53 operation_id: MessageId,
54 group_id: MemberId,
55 action: GroupAction<MemberId, ()>,
56 dependencies: Vec<MessageId>,
57) -> TestOperation {
58 let control_message = GroupControlMessage { group_id, action };
59 TestOperation {
60 id: operation_id,
61 author: actor_id,
62 dependencies,
63 payload: control_message,
64 }
65}
66
67pub fn create_group(
68 actor_id: MemberId,
69 operation_id: MessageId,
70 group_id: MemberId,
71 initial_members: Vec<(GroupMember<MemberId>, Access<()>)>,
72 dependencies: Vec<MessageId>,
73) -> TestOperation {
74 make_group_op(
75 actor_id,
76 operation_id,
77 group_id,
78 GroupAction::Create { initial_members },
79 dependencies,
80 )
81}
82
83pub fn add_member(
84 actor_id: MemberId,
85 operation_id: MessageId,
86 group_id: MemberId,
87 member: GroupMember<MemberId>,
88 access: Access<()>,
89 dependencies: Vec<MessageId>,
90) -> TestOperation {
91 make_group_op(
92 actor_id,
93 operation_id,
94 group_id,
95 GroupAction::Add { member, access },
96 dependencies,
97 )
98}
99
100pub fn remove_member(
101 actor_id: MemberId,
102 operation_id: MessageId,
103 group_id: MemberId,
104 member: GroupMember<MemberId>,
105 dependencies: Vec<MessageId>,
106) -> TestOperation {
107 make_group_op(
108 actor_id,
109 operation_id,
110 group_id,
111 GroupAction::Remove { member },
112 dependencies,
113 )
114}
115
116pub fn promote_member(
117 actor_id: MemberId,
118 operation_id: MessageId,
119 group_id: MemberId,
120 member: GroupMember<MemberId>,
121 access: Access<()>,
122 dependencies: Vec<MessageId>,
123) -> TestOperation {
124 make_group_op(
125 actor_id,
126 operation_id,
127 group_id,
128 GroupAction::Promote { member, access },
129 dependencies,
130 )
131}
132
133pub fn demote_member(
134 actor_id: MemberId,
135 operation_id: MessageId,
136 group_id: MemberId,
137 member: GroupMember<MemberId>,
138 access: Access<()>,
139 dependencies: Vec<MessageId>,
140) -> TestOperation {
141 make_group_op(
142 actor_id,
143 operation_id,
144 group_id,
145 GroupAction::Demote { member, access },
146 dependencies,
147 )
148}
149
150pub fn sync<ORD>(
151 y: GroupCrdtState<MemberId, MessageId, Conditions, ORD>,
152 ops: &[TestOperation],
153) -> GroupCrdtState<MemberId, MessageId, Conditions, ORD>
154where
155 ORD: Orderer<
156 MemberId,
157 MessageId,
158 GroupControlMessage<MemberId, Conditions>,
159 Operation = TestOperation,
160 > + Debug,
161 ORD::Operation: Clone,
162{
163 ops.iter().fold(y, |g, op| {
164 GroupCrdt::<MemberId, MessageId, Conditions, TestResolver, ORD>::process(g, op).unwrap()
165 })
166}
167
168pub fn assert_members<ORD>(
169 y: &GroupCrdtState<MemberId, MessageId, Conditions, ORD>,
170 group_id: MemberId,
171 expected: &[(char, Access<()>)],
172) where
173 ORD: Orderer<MemberId, MessageId, GroupControlMessage<MemberId, Conditions>> + Debug,
174 ORD::Operation: Clone,
175{
176 let mut actual = y.members(group_id);
177 let mut expected = expected.to_vec();
178 actual.sort();
179 expected.sort();
180 assert_eq!(actual, expected);
181}