use std::fmt::Display;
use serde::{Deserialize, Serialize};
use serde_with::{DisplayFromStr, serde_as};
use sui_sdk_types::{Address, Digest, StructTag, Version};
use crate::msgs::Owner;
use crate::serde::BigInt;
const OBJECT_DIGEST_DELETED: Digest = Digest::new([99; 32]);
const OBJECT_DIGEST_WRAPPED: Digest = Digest::new([88; 32]);
#[serde_as]
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum ObjectChange {
#[serde(rename_all = "camelCase")]
Published {
package_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
digest: Digest,
modules: Vec<String>,
},
#[serde(rename_all = "camelCase")]
Transferred {
sender: Address,
recipient: Owner,
#[serde_as(as = "DisplayFromStr")]
object_type: StructTag,
object_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
digest: Digest,
},
#[serde(rename_all = "camelCase")]
Mutated {
sender: Address,
owner: Owner,
#[serde_as(as = "DisplayFromStr")]
object_type: StructTag,
object_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
#[serde_as(as = "BigInt<u64>")]
previous_version: Version,
digest: Digest,
},
#[serde(rename_all = "camelCase")]
Deleted {
sender: Address,
#[serde_as(as = "DisplayFromStr")]
object_type: StructTag,
object_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
},
#[serde(rename_all = "camelCase")]
Wrapped {
sender: Address,
#[serde_as(as = "DisplayFromStr")]
object_type: StructTag,
object_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
},
#[serde(rename_all = "camelCase")]
Created {
sender: Address,
owner: Owner,
#[serde_as(as = "DisplayFromStr")]
object_type: StructTag,
object_id: Address,
#[serde_as(as = "BigInt<u64>")]
version: Version,
digest: Digest,
},
}
impl ObjectChange {
pub fn object_id(&self) -> Address {
match self {
ObjectChange::Published { package_id, .. } => *package_id,
ObjectChange::Transferred { object_id, .. }
| ObjectChange::Mutated { object_id, .. }
| ObjectChange::Deleted { object_id, .. }
| ObjectChange::Wrapped { object_id, .. }
| ObjectChange::Created { object_id, .. } => *object_id,
}
}
pub fn object_ref(&self) -> (Address, Version, Digest) {
match self {
ObjectChange::Published {
package_id,
version,
digest,
..
} => (*package_id, *version, *digest),
ObjectChange::Transferred {
object_id,
version,
digest,
..
}
| ObjectChange::Mutated {
object_id,
version,
digest,
..
}
| ObjectChange::Created {
object_id,
version,
digest,
..
} => (*object_id, *version, *digest),
ObjectChange::Deleted {
object_id, version, ..
} => (*object_id, *version, OBJECT_DIGEST_DELETED),
ObjectChange::Wrapped {
object_id, version, ..
} => (*object_id, *version, OBJECT_DIGEST_WRAPPED),
}
}
}
impl Display for ObjectChange {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
ObjectChange::Published {
package_id,
version,
digest,
modules,
} => {
write!(
f,
" ┌──\n │ PackageID: {} \n │ Version: {} \n │ Digest: {}\n │ Modules: {}\n └──",
package_id,
version,
digest,
modules.join(", ")
)
}
ObjectChange::Transferred {
sender,
recipient,
object_type,
object_id,
version,
digest,
} => {
write!(
f,
" ┌──\n │ Address: {}\n │ Sender: {} \n │ Recipient: {:?}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
object_id, sender, recipient, object_type, version, digest
)
}
ObjectChange::Mutated {
sender,
owner,
object_type,
object_id,
version,
previous_version: _,
digest,
} => {
write!(
f,
" ┌──\n │ Address: {}\n │ Sender: {} \n │ Owner: {:?}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
object_id, sender, owner, object_type, version, digest
)
}
ObjectChange::Deleted {
sender,
object_type,
object_id,
version,
} => {
write!(
f,
" ┌──\n │ Address: {}\n │ Sender: {} \n │ ObjectType: {} \n │ Version: {}\n └──",
object_id, sender, object_type, version
)
}
ObjectChange::Wrapped {
sender,
object_type,
object_id,
version,
} => {
write!(
f,
" ┌──\n │ Address: {}\n │ Sender: {} \n │ ObjectType: {} \n │ Version: {}\n └──",
object_id, sender, object_type, version
)
}
ObjectChange::Created {
sender,
owner,
object_type,
object_id,
version,
digest,
} => {
write!(
f,
" ┌──\n │ Address: {}\n │ Sender: {} \n │ Owner: {:?}\n │ ObjectType: {} \n │ Version: {}\n │ Digest: {}\n └──",
object_id, sender, owner, object_type, version, digest
)
}
}
}
}