[][src]Trait arbitrary::Arbitrary

pub trait Arbitrary: Sized + 'static {
    fn arbitrary(u: &mut Unstructured) -> Result<Self>;

    fn arbitrary_take_rest(u: Unstructured) -> Result<Self> { ... }
fn size_hint(depth: usize) -> (usize, Option<usize>) { ... }
fn shrink(&self) -> Box<dyn Iterator<Item = Self>> { ... } }

Generate arbitrary structured values from raw, unstructured data.

The Arbitrary trait allows you to generate valid structured values, like HashMaps, or ASTs, or MyTomlConfig, or any other data structure from raw, unstructured bytes provided by a fuzzer. It also features built-in shrinking, so that if you find a test case that triggers a bug, you can find the smallest, most easiest-to-understand test case that still triggers that bug.

Deriving Arbitrary

Automatically deriving the Arbitrary trait is the recommended way to implement Arbitrary for your types.

Using the custom derive requires that you enable the "derive" cargo feature in your Cargo.toml:

[dependencies]
arbitrary = { version = "0.2.0", features = ["derive"] }

Then, you add the #[derive(Arbitrary)] annotation to your struct or enum type definition:

use arbitrary::Arbitrary;
use std::collections::HashSet;

#[derive(Arbitrary)]
pub struct AddressBook {
    friends: HashSet<Friend>,
}

#[derive(Arbitrary, Hash, Eq, PartialEq)]
pub enum Friend {
    Buddy { name: String },
    Pal { age: usize },
}

Every member of the struct or enum must also implement Arbitrary.

Implementing Arbitrary By Hand

Implementing Arbitrary mostly involves nested calls to other Arbitrary arbitrary implementations for each of your struct or enum's members. But sometimes you need some amount of raw data, or you need to generate a variably-sized collection type, or you something of that sort. The Unstructured type helps you with these tasks.

use arbitrary::{Arbitrary, Result, Unstructured};

impl<T> Arbitrary for MyCollection<T>
where
    T: Arbitrary,
{
    fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
        // Get the number of `T`s we should insert into our collection.
        let len = u.arbitrary_len::<T>()?;

        // And then create a collection of that length!
        let mut my_collection = MyCollection::with_capacity(len);
        for _ in 0..len {
            let element = T::arbitrary(u)?;
            my_collection.insert(element);
        }

        Ok(my_collection)
    }
}

Required methods

fn arbitrary(u: &mut Unstructured) -> Result<Self>

Generate an arbitrary value of Self from the given unstructured data.

Calling Arbitrary::arbitrary requires that you have some raw data, perhaps given to you by a fuzzer like AFL or libFuzzer. You wrap this raw data in an Unstructured, and then you can call <MyType as Arbitrary>::arbitrary to construct an arbitrary instance of MyType from that unstuctured data.

Implementation may return an error if there is not enough data to construct a full instance of Self. This is generally OK: it is better to exit early and get the fuzzer to provide more input data, than it is to generate default values in place of the missing data, which would bias the distribution of generated values, and ultimately make fuzzing less efficient.

use arbitrary::{Arbitrary, Unstructured};

#[derive(Arbitrary)]
pub struct MyType {
    // ...
}

// Get the raw data from the fuzzer or wherever else.
let raw_data: &[u8] = get_raw_data_from_fuzzer();

// Wrap that raw data in an `Unstructured`.
let mut unstructured = Unstructured::new(raw_data);

// Generate an arbitrary instance of `MyType` and do stuff with it.
if let Ok(value) = MyType::arbitrary(&mut unstructured) {
    do_stuff(value);
}

See also the documentation for Unstructured.

Loading content...

Provided methods

fn arbitrary_take_rest(u: Unstructured) -> Result<Self>

Generate an arbitrary value of Self from the entirety of the given unstructured data.

This is similar to Arbitrary::arbitrary, however it assumes that it is the last consumer of the given data, and is thus able to consume it all if it needs. See also the documentation for Unstructured.

fn size_hint(depth: usize) -> (usize, Option<usize>)

Get a size hint for how many bytes out of an Unstructured this type needs to construct itself.

This is useful for determining how many elements we should insert when creating an arbitrary collection.

The return value is similar to Iterator::size_hint: it returns a tuple where the first element is a lower bound on the number of bytes required, and the second element is an optional upper bound.

The default implementation return (0, None) which is correct for any type, but not ultimately that useful. Using #[derive(Arbitrary)] will create a better implementation. If you are writing an Arbitrary implementation by hand, and your type can be part of a dynamically sized collection (such as Vec), you are strongly encouraged to override this default with a better implementation. The size_hint module will help with this task.

The depth Parameter

If you 100% know that the type you are implementing Arbitrary for is not a recursive type, or your implementation is not transitively calling any other size_hint methods, you can ignore the depth parameter. Note that if you are implementing Arbitrary for a generic type, you cannot guarantee the lack of type recrusion!

Otherwise, you need to use arbitrary::size_hint::recursion_guard(depth) to prevent potential infinite recursion when calculating size hints for potentially recursive types:

use arbitrary::{Arbitrary, Unstructured, size_hint};

// This can potentially be a recursive type if `L` or `R` contain
// something like `Box<Option<MyEither<L, R>>>`!
enum MyEither<L, R> {
    Left(L),
    Right(R),
}

impl<L, R> Arbitrary for MyEither<L, R>
where
    L: Arbitrary,
    R: Arbitrary,
{
    fn arbitrary(u: &mut Unstructured) -> arbitrary::Result<Self> {
        // ...
    }

    fn size_hint(depth: usize) -> (usize, Option<usize>) {
        // Protect against potential infinite recursion with
        // `recursion_guard`.
        size_hint::recursion_guard(depth, |depth| {
            // If we aren't too deep, then `recursion_guard` calls
            // this closure, which implements the natural size hint.
            // Don't forget to use the new `depth` in all nested
            // `size_hint` calls! We recommend shadowing the
            // parameter, like what is done here, so that you can't
            // accidentally use the wrong depth.
            size_hint::or(
                <L as Arbitrary>::size_hint(depth),
                <R as Arbitrary>::size_hint(depth),
            )
        })
    }
}

fn shrink(&self) -> Box<dyn Iterator<Item = Self>>

Generate an iterator of derived values which are "smaller" than the original self instance.

You can use this to help find the smallest test case that reproduces a bug.

Using #[derive(Arbitrary)] will automatically implement shrinking for your type.

However, if you are implementing Arbirary by hand and you want support for shrinking your type, you must override the default provided implementation of shrink, which just returns an empty iterator. You should try pretty hard to have your shrink implementation return a lazy iterator: one that computes the next value as it is needed, rather than computing them up front when shrink is first called.

Loading content...

Implementations on Foreign Types

impl Arbitrary for ()[src]

impl Arbitrary for bool[src]

impl Arbitrary for u8[src]

impl Arbitrary for u16[src]

impl Arbitrary for u32[src]

impl Arbitrary for u64[src]

impl Arbitrary for u128[src]

impl Arbitrary for usize[src]

impl Arbitrary for i8[src]

impl Arbitrary for i16[src]

impl Arbitrary for i32[src]

impl Arbitrary for i64[src]

impl Arbitrary for i128[src]

impl Arbitrary for isize[src]

impl Arbitrary for f32[src]

impl Arbitrary for f64[src]

impl Arbitrary for char[src]

impl Arbitrary for AtomicBool[src]

impl Arbitrary for AtomicIsize[src]

impl Arbitrary for AtomicUsize[src]

impl Arbitrary for Duration[src]

impl<A: Arbitrary> Arbitrary for Option<A>[src]

impl<A: Arbitrary, B: Arbitrary> Arbitrary for Result<A, B>[src]

impl<Z: Arbitrary> Arbitrary for (Z,)[src]

impl<Z: Arbitrary, Y: Arbitrary> Arbitrary for (Z, Y)[src]

impl<Y: Arbitrary, Z: Arbitrary, X: Arbitrary> Arbitrary for (Y, Z, X)[src]

impl<X: Arbitrary, Y: Arbitrary, Z: Arbitrary, W: Arbitrary> Arbitrary for (X, Y, Z, W)[src]

impl<W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, V: Arbitrary> Arbitrary for (W, X, Y, Z, V)[src]

impl<V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, U: Arbitrary> Arbitrary for (V, W, X, Y, Z, U)[src]

impl<U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, T: Arbitrary> Arbitrary for (U, V, W, X, Y, Z, T)[src]

impl<T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, S: Arbitrary> Arbitrary for (T, U, V, W, X, Y, Z, S)[src]

impl<S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, R: Arbitrary> Arbitrary for (S, T, U, V, W, X, Y, Z, R)[src]

impl<R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, Q: Arbitrary> Arbitrary for (R, S, T, U, V, W, X, Y, Z, Q)[src]

impl<Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, P: Arbitrary> Arbitrary for (Q, R, S, T, U, V, W, X, Y, Z, P)[src]

impl<P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, O: Arbitrary> Arbitrary for (P, Q, R, S, T, U, V, W, X, Y, Z, O)[src]

impl<O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, N: Arbitrary> Arbitrary for (O, P, Q, R, S, T, U, V, W, X, Y, Z, N)[src]

impl<N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, M: Arbitrary> Arbitrary for (N, O, P, Q, R, S, T, U, V, W, X, Y, Z, M)[src]

impl<M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, L: Arbitrary> Arbitrary for (M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, L)[src]

impl<L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, K: Arbitrary> Arbitrary for (L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, K)[src]

impl<K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, J: Arbitrary> Arbitrary for (K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, J)[src]

impl<J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, I: Arbitrary> Arbitrary for (J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, I)[src]

impl<I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, H: Arbitrary> Arbitrary for (I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, H)[src]

impl<H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, G: Arbitrary> Arbitrary for (H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, G)[src]

impl<G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, F: Arbitrary> Arbitrary for (G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, F)[src]

impl<F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, E: Arbitrary> Arbitrary for (F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, E)[src]

impl<E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, D: Arbitrary> Arbitrary for (E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, D)[src]

impl<D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, C: Arbitrary> Arbitrary for (D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, C)[src]

impl<C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, B: Arbitrary> Arbitrary for (C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, B)[src]

impl<B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary, J: Arbitrary, K: Arbitrary, L: Arbitrary, M: Arbitrary, N: Arbitrary, O: Arbitrary, P: Arbitrary, Q: Arbitrary, R: Arbitrary, S: Arbitrary, T: Arbitrary, U: Arbitrary, V: Arbitrary, W: Arbitrary, X: Arbitrary, Y: Arbitrary, Z: Arbitrary, A: Arbitrary> Arbitrary for (B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z, A)[src]

impl<T: Arbitrary> Arbitrary for [T; 1][src]

impl<T: Arbitrary> Arbitrary for [T; 2][src]

impl<T: Arbitrary> Arbitrary for [T; 3][src]

impl<T: Arbitrary> Arbitrary for [T; 4][src]

impl<T: Arbitrary> Arbitrary for [T; 5][src]

impl<T: Arbitrary> Arbitrary for [T; 6][src]

impl<T: Arbitrary> Arbitrary for [T; 7][src]

impl<T: Arbitrary> Arbitrary for [T; 8][src]

impl<T: Arbitrary> Arbitrary for [T; 9][src]

impl<T: Arbitrary> Arbitrary for [T; 10][src]

impl<T: Arbitrary> Arbitrary for [T; 11][src]

impl<T: Arbitrary> Arbitrary for [T; 12][src]

impl<T: Arbitrary> Arbitrary for [T; 13][src]

impl<T: Arbitrary> Arbitrary for [T; 14][src]

impl<T: Arbitrary> Arbitrary for [T; 15][src]

impl<T: Arbitrary> Arbitrary for [T; 16][src]

impl<T: Arbitrary> Arbitrary for [T; 17][src]

impl<T: Arbitrary> Arbitrary for [T; 18][src]

impl<T: Arbitrary> Arbitrary for [T; 19][src]

impl<T: Arbitrary> Arbitrary for [T; 20][src]

impl<T: Arbitrary> Arbitrary for [T; 21][src]

impl<T: Arbitrary> Arbitrary for [T; 22][src]

impl<T: Arbitrary> Arbitrary for [T; 23][src]

impl<T: Arbitrary> Arbitrary for [T; 24][src]

impl<T: Arbitrary> Arbitrary for [T; 25][src]

impl<T: Arbitrary> Arbitrary for [T; 26][src]

impl<T: Arbitrary> Arbitrary for [T; 27][src]

impl<T: Arbitrary> Arbitrary for [T; 28][src]

impl<T: Arbitrary> Arbitrary for [T; 29][src]

impl<T: Arbitrary> Arbitrary for [T; 30][src]

impl<T: Arbitrary> Arbitrary for [T; 31][src]

impl<T: Arbitrary> Arbitrary for [T; 32][src]

impl<A: Arbitrary> Arbitrary for Vec<A>[src]

impl<K: Arbitrary + Ord, V: Arbitrary> Arbitrary for BTreeMap<K, V>[src]

impl<A: Arbitrary + Ord> Arbitrary for BTreeSet<A>[src]

impl<A: Arbitrary + Ord> Arbitrary for BinaryHeap<A>[src]

impl<K: Arbitrary + Eq + Hash, V: Arbitrary> Arbitrary for HashMap<K, V>[src]

impl<A: Arbitrary + Eq + Hash> Arbitrary for HashSet<A>[src]

impl<A: Arbitrary> Arbitrary for LinkedList<A>[src]

impl<A: Arbitrary> Arbitrary for VecDeque<A>[src]

impl<A: ?Sized> Arbitrary for Cow<'static, A> where
    A: ToOwned,
    <A as ToOwned>::Owned: Arbitrary
[src]

impl Arbitrary for String[src]

impl Arbitrary for CString[src]

impl Arbitrary for OsString[src]

impl Arbitrary for PathBuf[src]

impl<A: Arbitrary> Arbitrary for Box<A>[src]

impl<A: Arbitrary> Arbitrary for Box<[A]>[src]

impl Arbitrary for Box<str>[src]

impl<A: Arbitrary> Arbitrary for Arc<A>[src]

impl<A: Arbitrary> Arbitrary for Rc<A>[src]

impl<A: Arbitrary> Arbitrary for Cell<A>[src]

impl<A: Arbitrary> Arbitrary for RefCell<A>[src]

impl<A: Arbitrary> Arbitrary for UnsafeCell<A>[src]

impl<A: Arbitrary> Arbitrary for Mutex<A>[src]

impl<A: Arbitrary> Arbitrary for Empty<A>[src]

impl<A: Arbitrary> Arbitrary for PhantomData<A>[src]

impl<A: Arbitrary> Arbitrary for Wrapping<A>[src]

Loading content...

Implementors

Loading content...