Skip to content

Commit

Permalink
Make Option<T> work with contracttype (#1145)
Browse files Browse the repository at this point in the history
### What
Try to make Option<T> work with contracttype

### Why
Close stellar/rs-soroban-env#444
Close #877

Dependent on:
- stellar/rs-stellar-xdr#320
- stellar/rs-soroban-env#1198
  • Loading branch information
leighmcculloch committed Nov 14, 2023
1 parent 77a760b commit 759deb6
Show file tree
Hide file tree
Showing 6 changed files with 284 additions and 25 deletions.
28 changes: 9 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Expand Up @@ -42,25 +42,25 @@ soroban-token-sdk = { version = "20.0.0-rc2", path = "soroban-token-sdk" }
[workspace.dependencies.soroban-env-common]
version = "20.0.0-rc2"
git = "https://github.com/stellar/rs-soroban-env"
rev = "472486c9dba96e09746522df0c9052cd50568e62"
rev = "d587d082d6b0d82f04730c9a67ac03ed9cc21dd6"

[workspace.dependencies.soroban-env-guest]
version = "20.0.0-rc2"
git = "https://github.com/stellar/rs-soroban-env"
rev = "472486c9dba96e09746522df0c9052cd50568e62"
rev = "d587d082d6b0d82f04730c9a67ac03ed9cc21dd6"

[workspace.dependencies.soroban-env-host]
version = "20.0.0-rc2"
git = "https://github.com/stellar/rs-soroban-env"
rev = "472486c9dba96e09746522df0c9052cd50568e62"
rev = "d587d082d6b0d82f04730c9a67ac03ed9cc21dd6"

[workspace.dependencies.stellar-strkey]
version = "0.0.8"

[workspace.dependencies.stellar-xdr]
version = "20.0.0-rc1"
git = "https://github.com/stellar/rs-stellar-xdr"
rev = "957273d7b8092888849219a3ad2aa054059ca89d"
rev = "d6f8ece2c89809d5e2800b9df64ae60787ee492b"
default-features = false
features = ["curr"]

Expand Down
1 change: 1 addition & 0 deletions soroban-sdk/src/tests.rs
Expand Up @@ -11,6 +11,7 @@ mod contract_overlapping_type_fn_names;
mod contract_snapshot;
mod contract_store;
mod contract_udt_enum;
mod contract_udt_option;
mod contract_udt_struct;
mod contract_udt_struct_tuple;
mod contractimport;
Expand Down
30 changes: 30 additions & 0 deletions soroban-sdk/src/tests/contract_udt_option.rs
@@ -0,0 +1,30 @@
use crate as soroban_sdk;
use soroban_sdk::{contract, contractimpl, contracttype, Env};

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
#[contracttype]
pub struct Udt {
pub a: i32,
pub b: Option<i32>,
}

#[contract]
pub struct Contract;

#[contractimpl]
impl Contract {
pub fn add(a: Udt, b: Udt) -> (Udt, Udt) {
(a, b)
}
}

#[test]
fn test_functional() {
let env = Env::default();
let contract_id = env.register_contract(None, Contract);

let a = Udt { a: 5, b: None };
let b = Udt { a: 10, b: Some(1) };
let c = ContractClient::new(&env, &contract_id).add(&a, &b);
assert_eq!(c, (a, b));
}
38 changes: 36 additions & 2 deletions soroban-sdk/src/testutils/arbitrary.rs
Expand Up @@ -317,19 +317,53 @@ mod objects {
use super::composite::ArbitraryVal;
use crate::env::FromVal;
use crate::ConversionError;
use crate::{Env, IntoVal, TryFromVal};
use crate::{Env, IntoVal, TryFromVal, TryIntoVal};

use crate::xdr::{Int256Parts, ScVal, UInt256Parts};
use crate::{
Address, Bytes, BytesN, Duration, Map, String, Symbol, Timepoint, Val, Vec, I256, U256,
};
use soroban_env_host::TryIntoVal;

use std::string::String as RustString;
use std::vec::Vec as RustVec;

//////////////////////////////////

#[derive(Arbitrary, Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct ArbitraryOption<T>(Option<T>);

impl<T> SorobanArbitrary for Option<T>
where
T: SorobanArbitrary,
Val: TryFromVal<Env, T::Prototype>,
Val: TryFromVal<Env, T>,
<T as TryFromVal<Env, Val>>::Error:
From<<Val as TryFromVal<Env, <T as SorobanArbitrary>::Prototype>>::Error>,
{
type Prototype = ArbitraryOption<T::Prototype>;
}

impl<T> TryFromVal<Env, ArbitraryOption<T::Prototype>> for Option<T>
where
T: SorobanArbitrary,
Val: TryFromVal<Env, T::Prototype>,
<T as TryFromVal<Env, Val>>::Error:
From<<Val as TryFromVal<Env, <T as SorobanArbitrary>::Prototype>>::Error>,
{
type Error = <T as TryFromVal<Env, Val>>::Error;
fn try_from_val(env: &Env, v: &ArbitraryOption<T::Prototype>) -> Result<Self, Self::Error> {
match v.0 {
Some(ref t) => {
let v = Val::try_from_val(env, t)?;
v.try_into_val(env)
}
None => Ok(None),
}
}
}

//////////////////////////////////

#[derive(Arbitrary, Debug, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct ArbitraryU256 {
parts: (u64, u64, u64, u64),
Expand Down

0 comments on commit 759deb6

Please sign in to comment.