Skip to content
1 change: 1 addition & 0 deletions crates/iota-sdk-ffi/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ pub mod gas;
pub mod graphql;
pub mod object;
pub mod signature;
pub mod struct_tag;
pub mod transaction;
pub mod type_tag;
55 changes: 55 additions & 0 deletions crates/iota-sdk-ffi/src/types/struct_tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::sync::Arc;

/// Type information for a move struct
///
/// # BCS
///
/// The BCS serialized form for this type is defined by the following ABNF:
///
/// ```text
/// struct-tag = address ; address of the package
/// identifier ; name of the module
/// identifier ; name of the type
/// (vector type-tag) ; type parameters
/// ```
#[derive(Clone, Debug, derive_more::From, uniffi::Object)]
pub struct StructTag(pub iota_types::StructTag);

#[uniffi::export]
impl StructTag {
#[uniffi::constructor]
pub fn coin(type_tag: &super::type_tag::TypeTag) -> Self {
Self(iota_types::StructTag::coin(type_tag.0.clone()))
}

/// Checks if this is a Coin type
pub fn coin_type_opt(&self) -> Option<Arc<super::type_tag::TypeTag>> {
self.0
.coin_type_opt()
.cloned()
.map(Into::into)
.map(Arc::new)
}

/// Checks if this is a Coin type
pub fn coin_type(&self) -> super::type_tag::TypeTag {
self.0.coin_type().clone().into()
}

#[uniffi::constructor]
pub fn gas_coin() -> Self {
Self(iota_types::StructTag::gas_coin())
}

#[uniffi::constructor]
pub fn staked_iota() -> Self {
Self(iota_types::StructTag::staked_iota())
}

pub fn address(&self) -> super::address::Address {
self.0.address().into()
}
}
197 changes: 197 additions & 0 deletions crates/iota-sdk-ffi/src/types/type_tag.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,202 @@
// Copyright (c) 2025 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::sync::Arc;

/// Type of a move value
///
/// # BCS
///
/// The BCS serialized form for this type is defined by the following ABNF:
///
/// ```text
/// type-tag = type-tag-u8 \
/// type-tag-u16 \
/// type-tag-u32 \
/// type-tag-u64 \
/// type-tag-u128 \
/// type-tag-u256 \
/// type-tag-bool \
/// type-tag-address \
/// type-tag-signer \
/// type-tag-vector \
/// type-tag-struct
///
/// type-tag-u8 = %x01
/// type-tag-u16 = %x08
/// type-tag-u32 = %x09
/// type-tag-u64 = %x02
/// type-tag-u128 = %x03
/// type-tag-u256 = %x0a
/// type-tag-bool = %x00
/// type-tag-address = %x04
/// type-tag-signer = %x05
/// type-tag-vector = %x06 type-tag
/// type-tag-struct = %x07 struct-tag
/// ```
#[derive(Clone, Debug, derive_more::From, uniffi::Object)]
pub struct TypeTag(pub iota_types::TypeTag);

#[uniffi::export]
impl TypeTag {
#[inline]
pub fn is_u8(&self) -> bool {
self.0.is_u8()
}

#[inline]
pub fn is_u16(&self) -> bool {
self.0.is_u16()
}

#[inline]
pub fn is_u32(&self) -> bool {
self.0.is_u32()
}

#[inline]
pub fn is_u64(&self) -> bool {
self.0.is_u64()
}

#[inline]
pub fn is_u128(&self) -> bool {
self.0.is_u128()
}

#[inline]
pub fn is_u256(&self) -> bool {
self.0.is_u256()
}

#[inline]
pub fn is_bool(&self) -> bool {
self.0.is_bool()
}

#[inline]
pub fn is_address(&self) -> bool {
self.0.is_address()
}

#[inline]
pub fn is_signer(&self) -> bool {
self.0.is_signer()
}

#[inline]
pub fn is_vector(&self) -> bool {
self.0.is_vector()
}

#[inline]
pub fn as_vector_type_tag_opt(&self) -> Option<Arc<TypeTag>> {
self.0
.as_vector_type_tag_opt()
.cloned()
.map(Into::into)
.map(Arc::new)
}

#[inline]
pub fn as_vector_type_tag(&self) -> TypeTag {
self.0.as_vector_type_tag().clone().into()
}

// TODO cannot take self?
#[inline]
pub fn into_vector_type_tag_opt(&self) -> Option<Arc<TypeTag>> {
self.clone()
.0
.into_vector_type_tag_opt()
.map(Into::into)
.map(Arc::new)
}

// TODO cannot take self?
#[inline]
pub fn into_vector_type_tag(&self) -> TypeTag {
self.clone().0.into_vector_type_tag().into()
}

#[inline]
pub fn is_struct(&self) -> bool {
self.0.is_struct()
}

#[inline]
pub fn as_struct_tag_opt(&self) -> Option<Arc<super::struct_tag::StructTag>> {
self.0
.as_struct_tag_opt()
.cloned()
.map(Into::into)
.map(Arc::new)
}

#[inline]
pub fn as_struct_tag(&self) -> super::struct_tag::StructTag {
self.0.as_struct_tag().clone().into()
}

// TODO cannot take self?
#[inline]
pub fn into_struct_tag_opt(&self) -> Option<Arc<super::struct_tag::StructTag>> {
self.clone()
.0
.into_struct_tag_opt()
.clone()
.map(Into::into)
.map(Arc::new)
}

// TODO cannot take self?
#[inline]
pub fn into_struct_tag(&self) -> super::struct_tag::StructTag {
self.clone().0.into_struct_tag().into()
}

#[uniffi::constructor]
pub fn u8() -> Self {
Self(iota_types::TypeTag::U8)
}

#[uniffi::constructor]
pub fn u16() -> Self {
Self(iota_types::TypeTag::U16)
}

#[uniffi::constructor]
pub fn u32() -> Self {
Self(iota_types::TypeTag::U32)
}

#[uniffi::constructor]
pub fn u64() -> Self {
Self(iota_types::TypeTag::U64)
}

#[uniffi::constructor]
pub fn u128() -> Self {
Self(iota_types::TypeTag::U128)
}

#[uniffi::constructor]
pub fn u256() -> Self {
Self(iota_types::TypeTag::U256)
}

#[uniffi::constructor]
pub fn bool() -> Self {
Self(iota_types::TypeTag::Bool)
}

#[uniffi::constructor]
pub fn address() -> Self {
Self(iota_types::TypeTag::Address)
}

#[uniffi::constructor]
pub fn signer() -> Self {
Self(iota_types::TypeTag::Signer)
}
}
14 changes: 7 additions & 7 deletions crates/iota-sdk-types/src/type_tag/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,32 @@ pub enum TypeTag {
impl TypeTag {
crate::def_is!(U8, U16, U32, U64, U128, U256, Bool, Address, Signer);

pub fn is_vector_type(&self) -> bool {
pub fn is_vector(&self) -> bool {
matches!(self, Self::Vector(_))
}

pub fn as_vector_type_opt(&self) -> Option<&TypeTag> {
pub fn as_vector_type_tag_opt(&self) -> Option<&TypeTag> {
if let Self::Vector(inner) = self {
Some(inner)
} else {
None
}
}

pub fn as_vector_type(&self) -> &TypeTag {
self.as_vector_type_opt().expect("not a Vector")
pub fn as_vector_type_tag(&self) -> &TypeTag {
self.as_vector_type_tag_opt().expect("not a Vector")
}

pub fn into_vector_type_opt(self) -> Option<TypeTag> {
pub fn into_vector_type_tag_opt(self) -> Option<TypeTag> {
if let Self::Vector(inner) = self {
Some(*inner)
} else {
None
}
}

pub fn into_vector_type(self) -> TypeTag {
self.into_vector_type_opt().expect("not a Vector type")
pub fn into_vector_type_tag(self) -> TypeTag {
self.into_vector_type_tag_opt().expect("not a Vector")
}

pub fn is_struct(&self) -> bool {
Expand Down