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