soroban_env_common/
arbitrary.rs

1//! Implementations of [`Arbitrary`] for contract types.
2
3extern crate alloc;
4
5use crate::symbol::MAX_SMALL_CHARS;
6use crate::xdr::ScError;
7use crate::{Error, StorageType, Symbol, SymbolSmall, Val, Void};
8use arbitrary::{Arbitrary, Unstructured};
9
10impl<'a> Arbitrary<'a> for Error {
11    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
12        let scerror = ScError::arbitrary(u)?;
13        let error = Error::from(scerror);
14        Ok(error)
15    }
16
17    fn size_hint(depth: usize) -> (usize, Option<usize>) {
18        <ScError as Arbitrary>::size_hint(depth)
19    }
20}
21
22impl<'a> Arbitrary<'a> for Void {
23    fn arbitrary(_u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
24        Ok(Val::VOID)
25    }
26
27    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
28        (0, Some(0))
29    }
30}
31
32impl<'a> Arbitrary<'a> for Symbol {
33    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
34        let len: usize = u.int_in_range(0..=MAX_SMALL_CHARS)?;
35        let mut buf = [0u8; MAX_SMALL_CHARS];
36        for i in 0..len {
37            buf[i] = (*u.choose(&[
38                'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
39                'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F',
40                'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
41                'W', 'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '_',
42            ])?) as u8;
43        }
44        let small =
45            SymbolSmall::try_from(&buf[0..len]).map_err(|_| arbitrary::Error::IncorrectFormat)?;
46        Ok(small.into())
47    }
48}
49
50impl<'a> Arbitrary<'a> for StorageType {
51    fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
52        u.choose(&[
53            StorageType::Instance,
54            StorageType::Persistent,
55            StorageType::Temporary,
56        ])
57        .map(|x| *x)
58    }
59
60    fn size_hint(depth: usize) -> (usize, Option<usize>) {
61        <usize as Arbitrary>::size_hint(depth)
62    }
63}