Skip to content

Commit 32edda4

Browse files
committed
wip: ABI value in utils ffi
1 parent dba9e17 commit 32edda4

File tree

15 files changed

+438
-0
lines changed

15 files changed

+438
-0
lines changed

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/algokit_utils_ffi/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ crate-type = ["lib", "cdylib", "staticlib"]
88

99
[dependencies]
1010
algod_client = { version = "0.0.1", path = "../algod_client", default-features = false }
11+
algokit_abi = { version = "0.1.0", path = "../algokit_abi" }
1112
algokit_http_client = { version = "0.1.0", path = "../algokit_http_client", features = ["ffi_uniffi"], default-features = false }
1213
algokit_transact = { version = "0.1.0", path = "../algokit_transact" }
1314
algokit_transact_ffi = { version = "0.1.0", path = "../algokit_transact_ffi" }
1415
algokit_utils = { version = "0.1.0", path = "../algokit_utils" }
1516
async-trait = "0.1.89"
1617
derive_more = "2.0.1"
18+
num-bigint = "0.4.6"
1719
snafu.workspace = true
1820
tokio = "1.47.1"
1921
uniffi = { workspace = true, features = [
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use algokit_abi::ABIType as RustABIType;
2+
3+
use super::{ABIType, FfiToRustABIType};
4+
5+
#[derive(uniffi::Object, Clone)]
6+
pub struct ABIAddress {}
7+
8+
impl From<ABIAddress> for RustABIType {
9+
fn from(_: ABIAddress) -> Self {
10+
RustABIType::Address
11+
}
12+
}
13+
14+
impl From<RustABIType> for ABIAddress {
15+
fn from(value: RustABIType) -> Self {
16+
if let RustABIType::Address = value {
17+
ABIAddress {}
18+
} else {
19+
panic!("Expected RustABIType::Address");
20+
}
21+
}
22+
}
23+
24+
impl FfiToRustABIType for ABIAddress {
25+
fn to_rust_abi_type(&self) -> RustABIType {
26+
(*self).clone().into()
27+
}
28+
}
29+
30+
impl ABIType for ABIAddress {}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use algokit_abi::ABIType as RustABIType;
2+
3+
use super::{ABIType, FfiToRustABIType};
4+
5+
#[derive(uniffi::Object, Clone)]
6+
pub struct ABIBool {}
7+
8+
impl From<ABIBool> for RustABIType {
9+
fn from(_: ABIBool) -> Self {
10+
RustABIType::Bool
11+
}
12+
}
13+
14+
impl From<RustABIType> for ABIBool {
15+
fn from(value: RustABIType) -> Self {
16+
if let RustABIType::Bool = value {
17+
ABIBool {}
18+
} else {
19+
panic!("Expected RustABIType::Bool");
20+
}
21+
}
22+
}
23+
24+
impl FfiToRustABIType for ABIBool {
25+
fn to_rust_abi_type(&self) -> RustABIType {
26+
(*self).clone().into()
27+
}
28+
}
29+
30+
impl ABIType for ABIBool {}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use super::{ABIType, FfiToRustABIType};
2+
use algokit_abi::ABIType as RustABIType;
3+
4+
#[derive(uniffi::Object, Clone)]
5+
pub struct ABIByte {}
6+
7+
impl From<ABIByte> for RustABIType {
8+
fn from(_: ABIByte) -> Self {
9+
RustABIType::Byte
10+
}
11+
}
12+
13+
impl From<RustABIType> for ABIByte {
14+
fn from(value: RustABIType) -> Self {
15+
if let RustABIType::Byte = value {
16+
ABIByte {}
17+
} else {
18+
panic!("Expected RustABIType::Byte");
19+
}
20+
}
21+
}
22+
23+
impl FfiToRustABIType for ABIByte {
24+
fn to_rust_abi_type(&self) -> RustABIType {
25+
(*self).clone().into()
26+
}
27+
}
28+
29+
impl ABIType for ABIByte {}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::sync::Arc;
2+
3+
use algokit_abi::ABIType as RustABIType;
4+
5+
use super::{ABIType, FfiToRustABIType, RustToFfiABIType};
6+
7+
#[derive(uniffi::Object, Clone)]
8+
pub struct ABIDynamicArray {
9+
element_type: Arc<dyn ABIType>,
10+
}
11+
12+
impl From<ABIDynamicArray> for RustABIType {
13+
fn from(value: ABIDynamicArray) -> Self {
14+
RustABIType::DynamicArray(Box::new(value.element_type.to_rust_abi_type()))
15+
}
16+
}
17+
18+
impl From<RustABIType> for ABIDynamicArray {
19+
fn from(value: RustABIType) -> Self {
20+
if let RustABIType::DynamicArray(rs_element_type) = value {
21+
ABIDynamicArray {
22+
element_type: rs_element_type.to_ffi_abi_type(),
23+
}
24+
} else {
25+
panic!("Expected RustABIType::DynamicArray");
26+
}
27+
}
28+
}
29+
30+
impl FfiToRustABIType for ABIDynamicArray {
31+
fn to_rust_abi_type(&self) -> RustABIType {
32+
(*self).clone().into()
33+
}
34+
}
35+
36+
impl ABIType for ABIDynamicArray {}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use std::sync::Arc;
2+
3+
use super::abi_value::ABIValue;
4+
use algokit_abi::ABIType as RustABIType;
5+
6+
mod address;
7+
mod bool;
8+
mod byte;
9+
mod dynamic_array;
10+
mod static_array;
11+
mod string;
12+
mod tuple;
13+
mod ufixed;
14+
mod uint;
15+
16+
// TODO: remove unwraps in this module
17+
18+
/// This trait is used to convert FFI ABI types to Rust ABI types
19+
/// This is needed because we can't implement From on Arc<dyn ABIType>
20+
pub trait FfiToRustABIType {
21+
/// Convert the FFI ABI type to a Rust ABI type
22+
fn to_rust_abi_type(&self) -> RustABIType;
23+
}
24+
25+
/// This trait is used to convert Rust ABI types to FFI ABI types
26+
/// This is needed because we can't implement From on Arc<dyn ABIType>
27+
trait RustToFfiABIType {
28+
fn to_ffi_abi_type(&self) -> Arc<dyn ABIType>;
29+
}
30+
31+
impl RustToFfiABIType for RustABIType {
32+
fn to_ffi_abi_type(&self) -> Arc<dyn ABIType> {
33+
let abi_type: Arc<dyn ABIType> = match self {
34+
RustABIType::Uint(_) => Arc::new(uint::ABIUint::from(self.clone())),
35+
RustABIType::Tuple(_) => Arc::new(tuple::ABITuple::from(self.clone())),
36+
RustABIType::UFixed(_, _) => Arc::new(ufixed::ABIUfixed::from(self.clone())),
37+
RustABIType::String => Arc::new(string::ABIString::from(self.clone())),
38+
RustABIType::Byte => Arc::new(byte::ABIByte::from(self.clone())),
39+
RustABIType::Bool => Arc::new(bool::ABIBool::from(self.clone())),
40+
RustABIType::DynamicArray(_) => {
41+
Arc::new(dynamic_array::ABIDynamicArray::from(self.clone()))
42+
}
43+
RustABIType::StaticArray(_, _) => {
44+
Arc::new(static_array::ABIStaticArray::from(self.clone()))
45+
}
46+
RustABIType::Address => Arc::new(address::ABIAddress::from(self.clone())),
47+
};
48+
abi_type
49+
}
50+
}
51+
52+
#[uniffi::export]
53+
pub trait ABIType: Send + Sync + FfiToRustABIType {
54+
fn decoode(&self, data: &[u8]) -> ABIValue {
55+
let rust_abi_type = self.to_rust_abi_type();
56+
ABIValue::from(rust_abi_type.decode(data).unwrap())
57+
}
58+
59+
fn encode(&self, value: ABIValue) -> Vec<u8> {
60+
let rust_abi_type = self.to_rust_abi_type();
61+
rust_abi_type.encode(&value.into()).unwrap()
62+
}
63+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use std::sync::Arc;
2+
3+
use algokit_abi::ABIType as RustABIType;
4+
5+
use super::{ABIType, FfiToRustABIType, RustToFfiABIType};
6+
7+
#[derive(uniffi::Object, Clone)]
8+
pub struct ABIStaticArray {
9+
element_type: Arc<dyn ABIType>,
10+
length: u32,
11+
}
12+
13+
impl From<ABIStaticArray> for RustABIType {
14+
fn from(value: ABIStaticArray) -> Self {
15+
RustABIType::StaticArray(
16+
Box::new(value.element_type.to_rust_abi_type()),
17+
value.length.try_into().unwrap(),
18+
)
19+
}
20+
}
21+
22+
impl From<RustABIType> for ABIStaticArray {
23+
fn from(value: RustABIType) -> Self {
24+
if let RustABIType::StaticArray(rs_element_type, rs_length) = value {
25+
ABIStaticArray {
26+
element_type: rs_element_type.to_ffi_abi_type(),
27+
length: rs_length.try_into().unwrap(),
28+
}
29+
} else {
30+
panic!("Expected RustABIType::StaticArray");
31+
}
32+
}
33+
}
34+
35+
impl FfiToRustABIType for ABIStaticArray {
36+
fn to_rust_abi_type(&self) -> RustABIType {
37+
(*self).clone().into()
38+
}
39+
}
40+
41+
impl ABIType for ABIStaticArray {}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use algokit_abi::ABIType as RustABIType;
2+
3+
use super::{ABIType, FfiToRustABIType};
4+
5+
#[derive(uniffi::Object, Clone)]
6+
pub struct ABIString {}
7+
8+
impl From<ABIString> for RustABIType {
9+
fn from(_: ABIString) -> Self {
10+
RustABIType::String
11+
}
12+
}
13+
14+
impl From<RustABIType> for ABIString {
15+
fn from(value: RustABIType) -> Self {
16+
if let RustABIType::String = value {
17+
ABIString {}
18+
} else {
19+
panic!("Expected RustABIType::String");
20+
}
21+
}
22+
}
23+
24+
impl FfiToRustABIType for ABIString {
25+
fn to_rust_abi_type(&self) -> RustABIType {
26+
(*self).clone().into()
27+
}
28+
}
29+
30+
impl ABIType for ABIString {}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use std::sync::Arc;
2+
3+
use algokit_abi::ABIType as RustABIType;
4+
5+
use super::RustToFfiABIType;
6+
use super::{ABIType, FfiToRustABIType};
7+
8+
#[derive(uniffi::Object, Clone)]
9+
pub struct ABITuple {
10+
components: Vec<Arc<dyn ABIType>>,
11+
}
12+
13+
impl FfiToRustABIType for ABITuple {
14+
fn to_rust_abi_type(&self) -> RustABIType {
15+
(*self).clone().into()
16+
}
17+
}
18+
19+
impl ABIType for ABITuple {}
20+
21+
impl From<ABITuple> for RustABIType {
22+
fn from(value: ABITuple) -> Self {
23+
let rust_components = value
24+
.components
25+
.into_iter()
26+
.map(|comp| comp.to_rust_abi_type())
27+
.collect();
28+
RustABIType::Tuple(rust_components)
29+
}
30+
}
31+
32+
impl From<RustABIType> for ABITuple {
33+
fn from(value: RustABIType) -> Self {
34+
if let RustABIType::Tuple(rust_components) = value {
35+
let components = rust_components
36+
.into_iter()
37+
.map(|comp| comp.to_ffi_abi_type())
38+
.collect();
39+
ABITuple { components }
40+
} else {
41+
panic!("Expected RustABIType::Tuple");
42+
}
43+
}
44+
}

0 commit comments

Comments
 (0)