Skip to content

Commit

Permalink
Implement Arbitrary for various types
Browse files Browse the repository at this point in the history
  • Loading branch information
brson committed Mar 7, 2023
1 parent fbd92a3 commit a7c4170
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

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

3 changes: 2 additions & 1 deletion soroban-env-common/Cargo.toml
Expand Up @@ -19,12 +19,13 @@ stellar-xdr = { workspace = true, default-features = false, features = [ "next"
wasmi = { workspace = true, optional = true }
serde = { version = "1.0.0", features = ["derive"], optional = true }
static_assertions = "1.1.0"
arbitrary = { version = "1.1.3", features = ["derive"], optional = true }

[features]
std = ["stellar-xdr/std", "stellar-xdr/base64"]
serde = ["dep:serde", "stellar-xdr/serde"]
vm = ["wasmi"]
testutils = []
testutils = ["dep:arbitrary", "stellar-xdr/arbitrary"]

[package.metadata.docs.rs]
all-features = true
68 changes: 68 additions & 0 deletions soroban-env-common/src/arbitrary.rs
@@ -0,0 +1,68 @@
//! Implementations of [`Arbitrary`] for contract types.

#![cfg(feature = "testutils")]

extern crate alloc;

use crate::symbol::Symbol;
use crate::xdr::{ScStatic, ScStatus};
use crate::{BitSet, RawVal, Static, Status};
use alloc::string::String;
use alloc::vec::Vec as RustVec;
use arbitrary::{Arbitrary, Unstructured};

impl<'a> Arbitrary<'a> for Symbol {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let choices = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
let choices: RustVec<char> = choices.chars().collect();

let mut buf = String::new();

let len = u.int_in_range(0..=10)?;

for _ in 0..len {
let choice = u.choose(&choices);
match choice {
Ok(ch) => {
buf.push(*ch);
}
Err(_) => {
break;
}
}
}

let symbol = Symbol::try_from_str(&buf).expect("Symbol");

Ok(symbol)
}
}

impl<'a> Arbitrary<'a> for BitSet {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let bits = u64::arbitrary(u)?;
let bits = bits & 0x0fff_ffff_ffff_ffff;

let bitset = BitSet::try_from_u64(bits).expect("BitSet");

Ok(bitset)
}
}

impl<'a> Arbitrary<'a> for Static {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let scval = ScStatic::arbitrary(u)?;
let rawval = RawVal::from_other_static(scval);
let staticval = Static::try_from(rawval).expect("Static");
Ok(staticval)
}
}

impl<'a> Arbitrary<'a> for Status {
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let scstatus = ScStatus::arbitrary(u)?;
let status = Status::from(scstatus);

Ok(status)
}
}
1 change: 1 addition & 0 deletions soroban-env-common/src/lib.rs
Expand Up @@ -36,6 +36,7 @@ pub const VERSION: Version = Version {

mod val_wrapper;

mod arbitrary;
mod array;
mod bitset;
mod compare;
Expand Down
2 changes: 1 addition & 1 deletion soroban-env-common/src/static.rs
Expand Up @@ -5,7 +5,7 @@ use stellar_xdr::ScStatic;
/// Wrapper for a [RawVal] that is tagged with [Tag::Static], interpreting the
/// [RawVal]'s body as a 32-bit value from a reserved set of "static" values
/// corresponding to the enumerated cases of [ScStatic].
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct Static(RawVal);

impl_wrapper_common!(Static);
Expand Down

0 comments on commit a7c4170

Please sign in to comment.