1use std::{
2 collections::{BTreeSet, HashSet},
3 hash::Hash,
4};
5
6use serde::{Deserialize, Serialize, Serializer};
7use serde_json::Value;
8
9#[cfg(feature = "typescript")]
10use ts_rs::TS;
11
12use crate::{Namespace, SchemaType};
13
14pub type MemberName = String;
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[cfg_attr(feature = "typescript", derive(TS))]
18#[cfg_attr(feature = "typescript", ts(export))]
19pub struct GovernanceEvent {
20 pub members: Option<MemberEvent>,
21 pub roles: Option<RolesEvent>,
22 pub schemas: Option<SchemasEvent>,
23 pub policies: Option<PoliciesEvent>,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28#[cfg_attr(feature = "typescript", derive(TS))]
29#[cfg_attr(feature = "typescript", ts(export))]
30pub struct MemberEvent {
31 pub add: Option<HashSet<NewMember>>,
32 pub remove: Option<HashSet<MemberName>>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
36#[cfg_attr(feature = "typescript", derive(TS))]
37#[cfg_attr(feature = "typescript", ts(export))]
38pub struct NewMember {
39 pub name: MemberName,
40 pub key: String,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
45#[cfg_attr(feature = "typescript", derive(TS))]
46#[cfg_attr(feature = "typescript", ts(export))]
47pub struct RolesEvent {
48 pub governance: Option<GovRoleEvent>,
49 pub tracker_schemas: Option<TrackerSchemasRoleEvent>,
50 pub schema: Option<HashSet<SchemaIdRole>>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
54#[cfg_attr(feature = "typescript", derive(TS))]
55#[cfg_attr(feature = "typescript", ts(export))]
56pub struct GovRoleEvent {
57 pub add: Option<GovRolesEvent>,
58 pub remove: Option<GovRolesEvent>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
62#[cfg_attr(feature = "typescript", derive(TS))]
63#[cfg_attr(feature = "typescript", ts(export))]
64pub struct SchemaIdRole {
65 pub schema_id: SchemaType,
66 pub add: Option<SchemaRolesAddEvent>,
67 pub remove: Option<SchemaRolesRemoveEvent>,
68 pub change: Option<SchemaRolesChangeEvent>,
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
72#[cfg_attr(feature = "typescript", derive(TS))]
73#[cfg_attr(feature = "typescript", ts(export))]
74pub struct TrackerSchemasRoleEvent {
75 pub add: Option<TrackerSchemasRolesAddEvent>,
76 pub remove: Option<TrackerSchemasRolesRemoveEvent>,
77 pub change: Option<TrackerSchemasRolesChangeEvent>,
78}
79
80#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
81#[cfg_attr(feature = "typescript", derive(TS))]
82#[cfg_attr(feature = "typescript", ts(export))]
83pub struct GovRolesEvent {
84 pub approver: Option<BTreeSet<MemberName>>,
85 pub evaluator: Option<BTreeSet<MemberName>>,
86 pub validator: Option<BTreeSet<MemberName>>,
87 pub witness: Option<BTreeSet<MemberName>>,
88 pub issuer: Option<BTreeSet<MemberName>>,
89}
90
91#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
92#[cfg_attr(feature = "typescript", derive(TS))]
93#[cfg_attr(feature = "typescript", ts(export))]
94pub struct TrackerSchemasRolesAddEvent {
95 pub evaluator: Option<BTreeSet<Role>>,
96 pub validator: Option<BTreeSet<Role>>,
97 pub witness: Option<BTreeSet<Role>>,
98 pub issuer: Option<BTreeSet<Role>>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
102#[cfg_attr(feature = "typescript", derive(TS))]
103#[cfg_attr(feature = "typescript", ts(export))]
104pub struct SchemaRolesAddEvent {
105 pub evaluator: Option<BTreeSet<Role>>,
106 pub validator: Option<BTreeSet<Role>>,
107 pub witness: Option<BTreeSet<Role>>,
108 pub creator: Option<BTreeSet<RoleCreator>>,
109 pub issuer: Option<BTreeSet<Role>>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
113#[cfg_attr(feature = "typescript", derive(TS))]
114#[cfg_attr(feature = "typescript", ts(export))]
115pub struct TrackerSchemasRolesRemoveEvent {
116 pub evaluator: Option<BTreeSet<Role>>,
117 pub validator: Option<BTreeSet<Role>>,
118 pub witness: Option<BTreeSet<Role>>,
119 pub issuer: Option<BTreeSet<Role>>,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
123#[cfg_attr(feature = "typescript", derive(TS))]
124#[cfg_attr(feature = "typescript", ts(export))]
125pub struct SchemaRolesRemoveEvent {
126 pub evaluator: Option<BTreeSet<Role>>,
127 pub validator: Option<BTreeSet<Role>>,
128 pub witness: Option<BTreeSet<Role>>,
129 pub creator: Option<BTreeSet<Role>>,
130 pub issuer: Option<BTreeSet<Role>>,
131}
132
133#[derive(
134 Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
135)]
136#[cfg_attr(feature = "typescript", derive(TS))]
137#[cfg_attr(feature = "typescript", ts(export))]
138pub struct TrackerSchemasRolesChangeEvent {
139 pub evaluator: Option<BTreeSet<RoleChange>>,
140 pub validator: Option<BTreeSet<RoleChange>>,
141 pub witness: Option<BTreeSet<RoleChange>>,
142 pub issuer: Option<BTreeSet<RoleChange>>,
143}
144
145#[derive(
146 Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
147)]
148#[cfg_attr(feature = "typescript", derive(TS))]
149#[cfg_attr(feature = "typescript", ts(export))]
150pub struct SchemaRolesChangeEvent {
151 pub evaluator: Option<BTreeSet<RoleChange>>,
152 pub validator: Option<BTreeSet<RoleChange>>,
153 pub witness: Option<BTreeSet<RoleChange>>,
154 pub creator: Option<BTreeSet<RoleCreatorChange>>,
155 pub issuer: Option<BTreeSet<RoleChange>>,
156}
157
158#[derive(
159 Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
160)]
161#[cfg_attr(feature = "typescript", derive(TS))]
162#[cfg_attr(feature = "typescript", ts(export))]
163pub struct RoleCreatorChange {
164 pub actual_name: MemberName,
165 pub actual_namespace: Namespace,
166 pub new_namespace: Option<Namespace>,
167 pub new_witnesses: Option<BTreeSet<String>>,
168 pub new_quantity: Option<CreatorQuantity>,
169}
170
171#[derive(
172 Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
173)]
174#[cfg_attr(feature = "typescript", derive(TS))]
175#[cfg_attr(feature = "typescript", ts(export))]
176pub struct RoleChange {
177 pub actual_name: MemberName,
178 pub actual_namespace: Namespace,
179 pub new_namespace: Namespace,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
184#[cfg_attr(feature = "typescript", derive(TS))]
185#[cfg_attr(feature = "typescript", ts(export))]
186pub struct SchemasEvent {
187 pub add: Option<HashSet<SchemaAdd>>,
188 pub remove: Option<HashSet<SchemaType>>,
189 pub change: Option<HashSet<SchemaChange>>,
190}
191
192#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
193#[cfg_attr(feature = "typescript", derive(TS))]
194#[cfg_attr(feature = "typescript", ts(export))]
195pub struct SchemaAdd {
196 pub id: SchemaType,
197 pub contract: String,
198 pub initial_value: Value,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize, Hash, Eq, PartialEq)]
202#[cfg_attr(feature = "typescript", derive(TS))]
203#[cfg_attr(feature = "typescript", ts(export))]
204pub struct SchemaChange {
205 pub actual_id: SchemaType,
206 pub new_contract: Option<String>,
207 pub new_initial_value: Option<Value>,
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
212#[cfg_attr(feature = "typescript", derive(TS))]
213#[cfg_attr(feature = "typescript", ts(export))]
214pub struct PoliciesEvent {
215 pub governance: Option<GovPolicieEvent>,
216 pub schema: Option<HashSet<SchemaIdPolicie>>,
217}
218
219#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
220#[cfg_attr(feature = "typescript", derive(TS))]
221#[cfg_attr(feature = "typescript", ts(export))]
222pub struct SchemaIdPolicie {
223 pub schema_id: SchemaType,
224 pub change: SchemaPolicieChange,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize)]
228#[cfg_attr(feature = "typescript", derive(TS))]
229#[cfg_attr(feature = "typescript", ts(export))]
230pub struct GovPolicieEvent {
231 pub change: GovPolicieChange,
232}
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
235#[cfg_attr(feature = "typescript", derive(TS))]
236#[cfg_attr(feature = "typescript", ts(export))]
237pub struct GovPolicieChange {
238 pub approve: Option<Quorum>,
239 pub evaluate: Option<Quorum>,
240 pub validate: Option<Quorum>,
241}
242
243#[derive(Debug, Clone, Serialize, Deserialize, Hash, PartialEq, Eq)]
244#[cfg_attr(feature = "typescript", derive(TS))]
245#[cfg_attr(feature = "typescript", ts(export))]
246pub struct SchemaPolicieChange {
247 pub evaluate: Option<Quorum>,
248 pub validate: Option<Quorum>,
249}
250
251#[derive(
253 Debug, Clone, Default, Serialize, Deserialize, PartialEq, Hash, Eq,
254)]
255#[cfg_attr(feature = "typescript", derive(TS))]
256#[cfg_attr(feature = "typescript", ts(export))]
257#[serde(rename_all = "lowercase")]
258pub enum Quorum {
259 #[default]
260 Majority,
261 Fixed(u32),
262 Percentage(u8),
263}
264
265#[derive(Debug, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
266#[cfg_attr(feature = "typescript", derive(TS))]
267#[cfg_attr(feature = "typescript", ts(export))]
268pub enum CreatorQuantity {
269 Quantity(u32),
270 Infinity,
271}
272
273impl<'de> Deserialize<'de> for CreatorQuantity {
274 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
275 where
276 D: serde::Deserializer<'de>,
277 {
278 let value = serde_json::Value::deserialize(deserializer)?;
279
280 match value {
281 serde_json::Value::String(s) if s == "infinity" => {
282 Ok(CreatorQuantity::Infinity)
283 }
284 serde_json::Value::Number(n) if n.is_u64() => {
285 Ok(CreatorQuantity::Quantity(n.as_u64().ok_or_else(|| {
286 serde::de::Error::custom(
287 "Quantity must be a number or 'infinity'",
288 )
289 })? as u32))
290 }
291 _ => Err(serde::de::Error::custom(
292 "Quantity must be a number or 'infinity'",
293 )),
294 }
295 }
296}
297
298impl Serialize for CreatorQuantity {
299 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
300 where
301 S: Serializer,
302 {
303 match self {
304 CreatorQuantity::Quantity(n) => serializer.serialize_u32(*n),
305 CreatorQuantity::Infinity => serializer.serialize_str("infinity"),
306 }
307 }
308}
309
310#[derive(
311 Debug, Serialize, Deserialize, Clone, PartialEq, Hash, Eq, PartialOrd, Ord,
312)]
313#[cfg_attr(feature = "typescript", derive(TS))]
314#[cfg_attr(feature = "typescript", ts(export))]
315pub struct Role {
316 pub name: String,
317 pub namespace: Namespace,
318}
319
320#[derive(Debug, Serialize, Deserialize, Clone)]
321#[cfg_attr(feature = "typescript", derive(TS))]
322#[cfg_attr(feature = "typescript", ts(export))]
323pub struct RoleCreator {
324 pub name: String,
325 pub namespace: Namespace,
326 pub witnesses: BTreeSet<String>,
327 pub quantity: CreatorQuantity,
328}
329
330impl Hash for RoleCreator {
331 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
332 self.name.hash(state);
333 self.namespace.hash(state);
334 }
335}
336
337impl PartialOrd for RoleCreator {
338 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
339 Some(self.cmp(other))
340 }
341}
342
343impl Ord for RoleCreator {
344 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
345 (self.name.clone(), self.namespace.clone())
346 .cmp(&(other.name.clone(), other.namespace.clone()))
347 }
348}
349
350impl PartialEq for RoleCreator {
351 fn eq(&self, other: &Self) -> bool {
352 self.name == other.name && self.namespace == other.namespace
353 }
354}
355
356impl Eq for RoleCreator {}