1use std::fmt::{Display, Formatter, Result};
6
7use iota_types::{
8 base_types::{IotaAddress, ObjectDigest, ObjectID, ObjectRef, SequenceNumber, StructTag},
9 iota_serde::IotaStructTag,
10 object::Owner,
11};
12use schemars::JsonSchema;
13use serde::{Deserialize, Serialize};
14use serde_with::serde_as;
15
16use crate::{
17 iota_owner::OwnerSchema,
18 iota_primitives::{
19 Base58 as Base58Schema, IotaAddress as IotaAddressSchema, ObjectID as ObjectIDSchema,
20 SequenceNumberString as SequenceNumberStringSchema, StructTag as StructTagSchema,
21 },
22};
23
24#[serde_as]
27#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, PartialEq, Eq)]
28#[serde(rename_all = "camelCase", tag = "type")]
29pub enum ObjectChange {
30 #[serde(rename_all = "camelCase")]
32 Published {
33 #[schemars(with = "ObjectIDSchema")]
34 package_id: ObjectID,
35 #[schemars(with = "SequenceNumberStringSchema")]
36 #[serde_as(as = "SequenceNumberStringSchema")]
37 version: SequenceNumber,
38 #[schemars(with = "Base58Schema")]
39 digest: ObjectDigest,
40 modules: Vec<String>,
41 },
42 #[serde(rename_all = "camelCase")]
44 Transferred {
45 #[schemars(with = "IotaAddressSchema")]
46 sender: IotaAddress,
47 #[schemars(with = "OwnerSchema")]
48 #[serde_as(as = "OwnerSchema")]
49 recipient: Owner,
50 #[schemars(with = "StructTagSchema")]
51 #[serde_as(as = "StructTagSchema")]
52 object_type: StructTag,
53 #[schemars(with = "ObjectIDSchema")]
54 object_id: ObjectID,
55 #[schemars(with = "SequenceNumberStringSchema")]
56 #[serde_as(as = "SequenceNumberStringSchema")]
57 version: SequenceNumber,
58 #[schemars(with = "Base58Schema")]
59 digest: ObjectDigest,
60 },
61 #[serde(rename_all = "camelCase")]
63 Mutated {
64 #[schemars(with = "IotaAddressSchema")]
65 sender: IotaAddress,
66 #[schemars(with = "OwnerSchema")]
67 #[serde_as(as = "OwnerSchema")]
68 owner: Owner,
69 #[schemars(with = "StructTagSchema")]
70 #[serde_as(as = "StructTagSchema")]
71 object_type: StructTag,
72 #[schemars(with = "ObjectIDSchema")]
73 object_id: ObjectID,
74 #[schemars(with = "SequenceNumberStringSchema")]
75 #[serde_as(as = "SequenceNumberStringSchema")]
76 version: SequenceNumber,
77 #[schemars(with = "SequenceNumberStringSchema")]
78 #[serde_as(as = "SequenceNumberStringSchema")]
79 previous_version: SequenceNumber,
80 #[schemars(with = "Base58Schema")]
81 digest: ObjectDigest,
82 },
83 #[serde(rename_all = "camelCase")]
85 Deleted {
86 #[schemars(with = "IotaAddressSchema")]
87 sender: IotaAddress,
88 #[schemars(with = "StructTagSchema")]
89 #[serde_as(as = "StructTagSchema")]
90 object_type: StructTag,
91 #[schemars(with = "ObjectIDSchema")]
92 object_id: ObjectID,
93 #[schemars(with = "SequenceNumberStringSchema")]
94 #[serde_as(as = "SequenceNumberStringSchema")]
95 version: SequenceNumber,
96 },
97 #[serde(rename_all = "camelCase")]
99 Wrapped {
100 #[schemars(with = "IotaAddressSchema")]
101 sender: IotaAddress,
102 #[schemars(with = "StructTagSchema")]
103 #[serde_as(as = "StructTagSchema")]
104 object_type: StructTag,
105 #[schemars(with = "ObjectIDSchema")]
106 object_id: ObjectID,
107 #[schemars(with = "SequenceNumberStringSchema")]
108 #[serde_as(as = "SequenceNumberStringSchema")]
109 version: SequenceNumber,
110 },
111 #[serde(rename_all = "camelCase")]
113 Unwrapped {
114 #[schemars(with = "IotaAddressSchema")]
115 sender: IotaAddress,
116 #[schemars(with = "OwnerSchema")]
117 #[serde_as(as = "OwnerSchema")]
118 owner: Owner,
119 #[schemars(with = "String")]
120 #[serde_as(as = "IotaStructTag")]
121 object_type: StructTag,
122 #[schemars(with = "ObjectIDSchema")]
123 object_id: ObjectID,
124 #[schemars(with = "SequenceNumberStringSchema")]
125 #[serde_as(as = "SequenceNumberStringSchema")]
126 version: SequenceNumber,
127 #[schemars(with = "Base58Schema")]
128 digest: ObjectDigest,
129 },
130 #[serde(rename_all = "camelCase")]
132 Created {
133 #[schemars(with = "IotaAddressSchema")]
134 sender: IotaAddress,
135 #[schemars(with = "OwnerSchema")]
136 #[serde_as(as = "OwnerSchema")]
137 owner: Owner,
138 #[schemars(with = "StructTagSchema")]
139 #[serde_as(as = "StructTagSchema")]
140 object_type: StructTag,
141 #[schemars(with = "ObjectIDSchema")]
142 object_id: ObjectID,
143 #[schemars(with = "SequenceNumberStringSchema")]
144 #[serde_as(as = "SequenceNumberStringSchema")]
145 version: SequenceNumber,
146 #[schemars(with = "Base58Schema")]
147 digest: ObjectDigest,
148 },
149}
150
151impl ObjectChange {
152 pub fn object_id(&self) -> ObjectID {
153 match self {
154 ObjectChange::Published { package_id, .. } => *package_id,
155 ObjectChange::Transferred { object_id, .. }
156 | ObjectChange::Mutated { object_id, .. }
157 | ObjectChange::Deleted { object_id, .. }
158 | ObjectChange::Wrapped { object_id, .. }
159 | ObjectChange::Unwrapped { object_id, .. }
160 | ObjectChange::Created { object_id, .. } => *object_id,
161 }
162 }
163
164 pub fn object_ref(&self) -> ObjectRef {
165 match self {
166 ObjectChange::Published {
167 package_id,
168 version,
169 digest,
170 ..
171 } => ObjectRef::new(*package_id, *version, *digest),
172 ObjectChange::Transferred {
173 object_id,
174 version,
175 digest,
176 ..
177 }
178 | ObjectChange::Mutated {
179 object_id,
180 version,
181 digest,
182 ..
183 }
184 | ObjectChange::Unwrapped {
185 object_id,
186 version,
187 digest,
188 ..
189 }
190 | ObjectChange::Created {
191 object_id,
192 version,
193 digest,
194 ..
195 } => ObjectRef::new(*object_id, *version, *digest),
196 ObjectChange::Deleted {
197 object_id, version, ..
198 } => ObjectRef::new(*object_id, *version, ObjectDigest::OBJECT_DELETED),
199 ObjectChange::Wrapped {
200 object_id, version, ..
201 } => ObjectRef::new(*object_id, *version, ObjectDigest::OBJECT_WRAPPED),
202 }
203 }
204
205 pub fn mask_for_test(&mut self, new_version: SequenceNumber, new_digest: ObjectDigest) {
206 match self {
207 ObjectChange::Published {
208 version, digest, ..
209 }
210 | ObjectChange::Transferred {
211 version, digest, ..
212 }
213 | ObjectChange::Mutated {
214 version, digest, ..
215 }
216 | ObjectChange::Unwrapped {
217 version, digest, ..
218 }
219 | ObjectChange::Created {
220 version, digest, ..
221 } => {
222 *version = new_version;
223 *digest = new_digest
224 }
225 ObjectChange::Deleted { version, .. } | ObjectChange::Wrapped { version, .. } => {
226 *version = new_version
227 }
228 }
229 }
230}
231
232impl Display for ObjectChange {
233 fn fmt(&self, f: &mut Formatter) -> Result {
234 match self {
235 ObjectChange::Published {
236 package_id,
237 version,
238 digest,
239 modules,
240 } => {
241 write!(
242 f,
243 " ┌──\n │ PackageID: {} \n │ Version: {} \n │ Digest: {}\n │ Modules: {}\n └──",
244 package_id,
245 version,
246 digest,
247 modules.join(", ")
248 )
249 }
250 ObjectChange::Transferred {
251 sender,
252 recipient,
253 object_type,
254 object_id,
255 version,
256 digest,
257 } => {
258 write!(
259 f,
260 " ┌──\n │ ObjectID: {object_id}\n │ Sender: {sender} \n │ Recipient: {recipient}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
261 )
262 }
263 ObjectChange::Mutated {
264 sender,
265 owner,
266 object_type,
267 object_id,
268 version,
269 previous_version: _,
270 digest,
271 } => {
272 write!(
273 f,
274 " ┌──\n │ ObjectID: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
275 )
276 }
277 ObjectChange::Deleted {
278 sender,
279 object_type,
280 object_id,
281 version,
282 } => {
283 write!(
284 f,
285 " ┌──\n │ ObjectID: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
286 )
287 }
288 ObjectChange::Wrapped {
289 sender,
290 object_type,
291 object_id,
292 version,
293 } => {
294 write!(
295 f,
296 " ┌──\n │ ObjectID: {object_id}\n │ Sender: {sender} \n │ ObjectType: {object_type} \n │ Version: {version}\n └──"
297 )
298 }
299 ObjectChange::Unwrapped {
300 sender,
301 owner,
302 object_type,
303 object_id,
304 version,
305 digest,
306 } => {
307 write!(
308 f,
309 " ┌──\n │ ObjectID: {}\n │ Sender: {} \n │ Owner: {}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
310 object_id,
311 sender,
312 owner,
313 object_type,
314 version.as_u64(),
315 digest
316 )
317 }
318 ObjectChange::Created {
319 sender,
320 owner,
321 object_type,
322 object_id,
323 version,
324 digest,
325 } => {
326 write!(
327 f,
328 " ┌──\n │ ObjectID: {object_id}\n │ Sender: {sender} \n │ Owner: {owner}\n │ ObjectType: {object_type} \n │ Version: {version}\n │ Digest: {digest}\n └──"
329 )
330 }
331 }
332 }
333}