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