Skip to content

Commit 020ed34

Browse files
committed
ffi: implement Display for TransactionEffectsV1
1 parent 54106f5 commit 020ed34

File tree

6 files changed

+34709
-31632
lines changed

6 files changed

+34709
-31632
lines changed

bindings/python/lib/iota_sdk_ffi.py

Lines changed: 34544 additions & 31617 deletions
Large diffs are not rendered by default.

crates/iota-sdk-ffi/Cargo.toml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,12 @@ base64ct = { version = "1.6.0", features = ["alloc", "std"] }
1818
bcs = "0.1.6"
1919
derive_more = { version = "2.0", features = ["from", "deref", "display"] }
2020
hex = "0.4.3"
21-
rand = "0.8"
22-
roaring = { version = "0.11.2", default-features = false }
23-
serde_json = "1.0.95"
24-
tokio = { version = "1.36.0", features = ["time"] }
25-
uniffi = { version = "0.29", features = ["cli", "tokio"] }
26-
2721
iota-crypto = { path = "../iota-crypto", features = ["bls12381", "ed25519", "secp256r1", "passkey", "secp256k1", "zklogin", "pem"] }
2822
iota-graphql-client = { path = "../iota-graphql-client" }
2923
iota-transaction-builder = { path = "../iota-transaction-builder" }
3024
iota-types = { package = "iota-sdk-types", path = "../iota-sdk-types", features = ["hash", "rand"] }
25+
rand = "0.8"
26+
roaring = { version = "0.11.2", default-features = false }
27+
serde_json = "1.0.95"
28+
tokio = { version = "1.36.0", features = ["time"] }
29+
uniffi = { git = "https://github.com/mozilla/uniffi-rs", features = ["cli", "tokio"] }

crates/iota-sdk-ffi/src/types/digest.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ use crate::error::Result;
1717
/// IOTA's binary representation of a `Digest` is prefixed with its length
1818
/// meaning its serialized binary form (in bcs) is 33 bytes long vs a more
1919
/// compact 32 bytes.
20-
#[derive(derive_more::From, derive_more::Deref, uniffi::Object)]
20+
// Implement Display via derive_more so wrapper delegates to inner type's Display.
21+
#[derive(Debug, derive_more::From, derive_more::Deref, derive_more::Display, uniffi::Object)]
22+
#[uniffi::export(Display)]
2123
pub struct Digest(pub iota_types::Digest);
2224

2325
#[uniffi::export]

crates/iota-sdk-ffi/src/types/execution_status.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ pub enum ExecutionStatus {
3636
},
3737
}
3838

39+
impl std::fmt::Display for ExecutionStatus {
40+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
41+
match self {
42+
Self::Success => write!(f, "SUCCESS"),
43+
Self::Failure { .. } => write!(f, "FAILURE"),
44+
}
45+
}
46+
}
47+
3948
impl From<iota_types::ExecutionStatus> for ExecutionStatus {
4049
fn from(value: iota_types::ExecutionStatus) -> Self {
4150
match value {

crates/iota-sdk-ffi/src/types/object.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,16 @@ use crate::{
3737
/// ```text
3838
/// object-id = 32*OCTET
3939
/// ```
40-
#[derive(PartialEq, Eq, Hash, derive_more::From, derive_more::Deref, uniffi::Object)]
40+
#[derive(
41+
Debug,
42+
PartialEq,
43+
Eq,
44+
Hash,
45+
derive_more::From,
46+
derive_more::Deref,
47+
derive_more::Display,
48+
uniffi::Object,
49+
)]
4150
#[uniffi::export(Hash)]
4251
pub struct ObjectId(pub iota_types::ObjectId);
4352

@@ -481,7 +490,7 @@ impl From<MoveStruct> for iota_types::MoveStruct {
481490
/// owner-shared = %x02 u64
482491
/// owner-immutable = %x03
483492
/// ```
484-
#[derive(derive_more::From, derive_more::Deref, derive_more::Display, uniffi::Object)]
493+
#[derive(Debug, derive_more::From, derive_more::Deref, derive_more::Display, uniffi::Object)]
485494
#[uniffi::export(Display)]
486495
pub struct Owner(pub iota_types::Owner);
487496

crates/iota-sdk-ffi/src/types/transaction/v1.rs

Lines changed: 137 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2025 IOTA Stiftung
22
// SPDX-License-Identifier: Apache-2.0
33

4-
use std::sync::Arc;
4+
use std::{fmt, sync::Arc};
55

66
use iota_types::{GasCostSummary, IdOperation};
77

@@ -31,6 +31,7 @@ use crate::types::{
3131
/// (option digest) ; auxiliary data digest
3232
/// ```
3333
#[derive(uniffi::Record)]
34+
#[uniffi::export(Display)]
3435
pub struct TransactionEffectsV1 {
3536
/// The status of the execution
3637
pub status: ExecutionStatus,
@@ -69,6 +70,68 @@ pub struct TransactionEffectsV1 {
6970
pub auxiliary_data_digest: Option<Arc<Digest>>,
7071
}
7172

73+
impl fmt::Display for TransactionEffectsV1 {
74+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
75+
// Helper to format optional digest
76+
let fmt_opt_digest = |d: &Option<Arc<Digest>>| -> String {
77+
d.as_ref()
78+
.map(|v| v.to_string())
79+
.unwrap_or_else(|| "-".to_string())
80+
};
81+
let dependencies = if self.dependencies.is_empty() {
82+
String::from("[]")
83+
} else {
84+
format!(
85+
"[{}]",
86+
self.dependencies
87+
.iter()
88+
.map(|d| d.to_string())
89+
.collect::<Vec<_>>()
90+
.join(", ")
91+
)
92+
};
93+
let changed = if self.changed_objects.is_empty() {
94+
String::from("[]")
95+
} else {
96+
format!(
97+
"[{}]",
98+
self.changed_objects
99+
.iter()
100+
.map(|c| c.to_string())
101+
.collect::<Vec<_>>()
102+
.join(", ")
103+
)
104+
};
105+
let unchanged = if self.unchanged_shared_objects.is_empty() {
106+
String::from("[]")
107+
} else {
108+
format!(
109+
"[{}]",
110+
self.unchanged_shared_objects
111+
.iter()
112+
.map(|c| c.to_string())
113+
.collect::<Vec<_>>()
114+
.join(", ")
115+
)
116+
};
117+
write!(
118+
f,
119+
"TransactionEffectsV1(status={}, epoch={}, gas_used={}, tx_digest={}, gas_object_index={:?}, events_digest={}, dependencies={}, lamport_version={}, changed_objects={}, unchanged_shared_objects={}, auxiliary_data_digest={})",
120+
self.status,
121+
self.epoch,
122+
self.gas_used,
123+
self.transaction_digest,
124+
self.gas_object_index,
125+
fmt_opt_digest(&self.events_digest),
126+
dependencies,
127+
self.lamport_version,
128+
changed,
129+
unchanged,
130+
fmt_opt_digest(&self.auxiliary_data_digest)
131+
)
132+
}
133+
}
134+
72135
impl From<iota_types::TransactionEffectsV1> for TransactionEffectsV1 {
73136
fn from(value: iota_types::TransactionEffectsV1) -> Self {
74137
Self {
@@ -127,7 +190,8 @@ impl From<TransactionEffectsV1> for iota_types::TransactionEffectsV1 {
127190
/// ```text
128191
/// changed-object = object-id object-in object-out id-operation
129192
/// ```
130-
#[derive(uniffi::Record)]
193+
#[derive(Debug, uniffi::Record)]
194+
#[uniffi::export(Display)]
131195
pub struct ChangedObject {
132196
/// Id of the object
133197
pub object_id: Arc<ObjectId>,
@@ -141,6 +205,12 @@ pub struct ChangedObject {
141205
pub id_operation: IdOperation,
142206
}
143207

208+
impl fmt::Display for ChangedObject {
209+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210+
write!(f, "ChangedObject(object_id={})", self.object_id)
211+
}
212+
}
213+
144214
impl From<iota_types::ChangedObject> for ChangedObject {
145215
fn from(value: iota_types::ChangedObject) -> Self {
146216
Self {
@@ -172,12 +242,23 @@ impl From<ChangedObject> for iota_types::ChangedObject {
172242
/// ```text
173243
/// unchanged-shared-object = object-id unchanged-shared-object-kind
174244
/// ```
175-
#[derive(uniffi::Record)]
245+
#[derive(Debug, uniffi::Record)]
246+
#[uniffi::export(Display)]
176247
pub struct UnchangedSharedObject {
177248
pub object_id: Arc<ObjectId>,
178249
pub kind: UnchangedSharedKind,
179250
}
180251

252+
impl fmt::Display for UnchangedSharedObject {
253+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
254+
write!(
255+
f,
256+
"UnchangedSharedObject(object_id={}, kind={})",
257+
self.object_id, self.kind
258+
)
259+
}
260+
}
261+
181262
impl From<iota_types::UnchangedSharedObject> for UnchangedSharedObject {
182263
fn from(value: iota_types::UnchangedSharedObject) -> Self {
183264
Self {
@@ -215,7 +296,7 @@ impl From<UnchangedSharedObject> for iota_types::UnchangedSharedObject {
215296
/// cancelled = %x03 u64
216297
/// per-epoch-config = %x04
217298
/// ```
218-
#[derive(uniffi::Enum)]
299+
#[derive(Debug, uniffi::Enum)]
219300
pub enum UnchangedSharedKind {
220301
/// Read-only shared objects from the input. We don't really need
221302
/// ObjectDigest for protocol correctness, but it will make it easier to
@@ -285,7 +366,7 @@ impl From<UnchangedSharedKind> for iota_types::UnchangedSharedKind {
285366
/// object-in-missing = %x00
286367
/// object-in-data = %x01 u64 digest owner
287368
/// ```
288-
#[derive(uniffi::Enum)]
369+
#[derive(Debug, uniffi::Enum)]
289370
pub enum ObjectIn {
290371
Missing,
291372
/// The old version, digest and owner.
@@ -346,7 +427,7 @@ impl From<ObjectIn> for iota_types::ObjectIn {
346427
/// object-out-object-write = %x01 digest owner
347428
/// object-out-package-write = %x02 version digest
348429
/// ```
349-
#[derive(uniffi::Enum)]
430+
#[derive(Debug, uniffi::Enum)]
350431
pub enum ObjectOut {
351432
/// Same definition as in ObjectIn.
352433
Missing,
@@ -376,6 +457,27 @@ impl From<iota_types::ObjectOut> for ObjectOut {
376457
}
377458
}
378459

460+
// Display impls for enums (placed after their definitions)
461+
impl fmt::Display for UnchangedSharedKind {
462+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
463+
match self {
464+
UnchangedSharedKind::ReadOnlyRoot { version, digest } => {
465+
write!(f, "ReadOnlyRoot(version={}, digest={})", version, digest)
466+
}
467+
UnchangedSharedKind::MutateDeleted { version } => {
468+
write!(f, "MutateDeleted(version={})", version)
469+
}
470+
UnchangedSharedKind::ReadDeleted { version } => {
471+
write!(f, "ReadDeleted(version={})", version)
472+
}
473+
UnchangedSharedKind::Cancelled { version } => {
474+
write!(f, "Cancelled(version={})", version)
475+
}
476+
UnchangedSharedKind::PerEpochConfig => write!(f, "PerEpochConfig"),
477+
}
478+
}
479+
}
480+
379481
impl From<ObjectOut> for iota_types::ObjectOut {
380482
fn from(value: ObjectOut) -> Self {
381483
match value {
@@ -392,6 +494,35 @@ impl From<ObjectOut> for iota_types::ObjectOut {
392494
}
393495
}
394496

497+
impl fmt::Display for ObjectIn {
498+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499+
match self {
500+
ObjectIn::Missing => write!(f, "Missing"),
501+
ObjectIn::Data {
502+
version,
503+
digest,
504+
owner: _,
505+
} => {
506+
write!(f, "Data(version={}, digest={})", version, digest)
507+
}
508+
}
509+
}
510+
}
511+
512+
impl fmt::Display for ObjectOut {
513+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
514+
match self {
515+
ObjectOut::Missing => write!(f, "Missing"),
516+
ObjectOut::ObjectWrite { digest, owner: _ } => {
517+
write!(f, "ObjectWrite(digest={})", digest)
518+
}
519+
ObjectOut::PackageWrite { version, digest } => {
520+
write!(f, "PackageWrite(version={}, digest={})", version, digest)
521+
}
522+
}
523+
}
524+
}
525+
395526
/// Defines what happened to an ObjectId during execution
396527
///
397528
/// # BCS

0 commit comments

Comments
 (0)