main
rs 128 lines 3.46 KB
Raw
1 use super::{BlockId, ParticipantId};
2 use byte_unit::Byte;
3 use serde::{Deserialize, Serialize};
4
5 /// The replica ID that a participant's CRDT-compliant input
6 /// buffer must use. This must be unique across a session.
7 ///
8 /// The sharer is allowed to choose their own replica ID.
9 #[derive(Clone, Default, Debug, Serialize, Deserialize)]
10 pub struct InputReplicaId(String);
11
12 impl From<String> for InputReplicaId {
13 fn from(value: String) -> Self {
14 Self(value)
15 }
16 }
17
18 impl std::fmt::Display for InputReplicaId {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 write!(f, "{}", self.0)
21 }
22 }
23
24 /// A monotonically increasing sequence number to identify sequential edits for a given buffer.
25 #[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq, Ord, PartialOrd)]
26 pub struct InputOperationSeqNo(usize);
27
28 impl InputOperationSeqNo {
29 pub fn zero() -> Self {
30 Self(0)
31 }
32
33 pub fn advance(&mut self) {
34 self.0 += 1;
35 }
36
37 pub fn as_usize(&self) -> usize {
38 self.0
39 }
40 }
41
42 impl From<usize> for InputOperationSeqNo {
43 fn from(value: usize) -> Self {
44 Self(value)
45 }
46 }
47
48 /// A [`BufferId`] identifies an instance of the buffer in a session.
49 /// For example, suppose a session starts with buffer_id=B1.
50 /// When a command is executed and the buffer is reset, the
51 /// buffer_id=B2, where B1 != B2.
52 ///
53 /// Today, a [`BufferId`] masquerades as a [`BlockId`].
54 #[derive(Clone, Debug, Default, Deserialize, Hash, Serialize, Eq, PartialEq)]
55 pub struct BufferId(String);
56
57 impl std::fmt::Display for BufferId {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "{}", self.0)
60 }
61 }
62
63 impl From<String> for BufferId {
64 fn from(value: String) -> Self {
65 Self(value)
66 }
67 }
68
69 impl From<BlockId> for BufferId {
70 fn from(value: BlockId) -> Self {
71 Self(value.to_string())
72 }
73 }
74
75 impl From<BufferId> for BlockId {
76 fn from(value: BufferId) -> Self {
77 value.0.into()
78 }
79 }
80
81 /// A CRDT-compliant operation.
82 /// For now, this is a arbitrary payload that clients should know
83 /// how to serialize / deserialize. Eventually, this will be a
84 /// strongly-typed data structure.
85 #[derive(Clone, Debug, Deserialize, Serialize)]
86 pub struct CrdtOperation(pub Vec<u8>);
87
88 /// A unique identifier for an input operation. Specifically,
89 /// this uniquely identifies an operation for a specific buffer,
90 /// for a given participant.
91 #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
92 pub struct InputOperationId {
93 /// The participant that made the change.
94 pub participant_id: ParticipantId,
95
96 /// The ID of the buffer that this operation was applied to.
97 pub buffer_id: BufferId,
98
99 /// A monotonically increasing sequence number to identify sequential edits
100 /// for a specific buffer.
101 pub op_no: InputOperationSeqNo,
102 }
103
104 #[derive(Clone, Debug, Deserialize, Serialize)]
105 pub struct InputUpdate {
106 pub id: InputOperationId,
107
108 /// A single input operation consists of a batch
109 /// of updates.
110 pub ops: Vec<CrdtOperation>,
111 }
112
113 impl InputUpdate {
114 pub fn num_bytes(&self) -> Byte {
115 self.ops
116 .iter()
117 .map(|op| op.0.len() as u64)
118 .fold(0, u64::saturating_add)
119 .into()
120 }
121 }
122
123 /// A set of reasons why a request to edit the input might fail.
124 #[derive(Clone, Debug, Deserialize, Serialize)]
125 pub enum InputUpdateFailureReason {
126 /// The viewer does not have sufficient permissions.
127 InsufficientPermissions,
128 }