#collection #combinator #standard #generate #ext #function #set

arbitrary_ext

Provides combinator functions to generate standard collections with custom arbitrary function

4 releases (2 breaking)

0.3.0 Nov 23, 2022
0.2.1 Oct 19, 2022
0.2.0 Oct 19, 2022
0.1.0 Oct 18, 2022

#336 in Testing

Download history 184/week @ 2024-03-14 177/week @ 2024-03-21 224/week @ 2024-03-28 113/week @ 2024-04-04 123/week @ 2024-04-11 103/week @ 2024-04-18 112/week @ 2024-04-25 228/week @ 2024-05-02 106/week @ 2024-05-09 109/week @ 2024-05-16 267/week @ 2024-05-23 148/week @ 2024-05-30 168/week @ 2024-06-06 188/week @ 2024-06-13 195/week @ 2024-06-20 179/week @ 2024-06-27

750 downloads per month
Used in 3 crates

MIT license

11KB
137 lines

Arbitrary Ext

Since 1.2.0 Arbitrary supports custom arbitrary implementation for fields on derive.

But it still remains tricky, if a type that does not implement Arbitrary is wrapped into a generic type.

This crate provides s set of function combinators to support the containers and collections form the standard library.

See the example below.

Usage

use arbitrary_ext::{arbitrary_option, arbitrary_vec, arbitrary_hash_map};
use std::collections::HashMap;

// Imagine this is a foreign type, that by some reason does not implement Arbitrary trait.
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct Number(u32);

// Our custom function to generate arbitrary Number out of Unstructured.
fn arbitrary_number(u: &mut Unstructured) -> arbitrary::Result<Number> {
    let value = u.int_in_range(0..=1000)?;
    Ok(Number(value))
}

#[derive(Debug, Arbitrary)]
struct Example {
    #[arbitrary(with = arbitrary_number)]
    number: Number,

    #[arbitrary(with = arbitrary_option(arbitrary_number))]
    option: Option<Number>,

    #[arbitrary(with = arbitrary_vec(arbitrary_number))]
    vec: Vec<Number>,

    #[arbitrary(
        with = arbitrary_hash_map(
            arbitrary_number,
            arbitrary_vec(arbitrary_option(arbitrary_number))
        )
    )]
    hash_map: HashMap<Number, Vec<Option<Number>>>,
}

Without having arbitrary_option, arbitrary_vec, arbitrary_hash_map combinators, would be forced to implement out custom functions to generate arbitrary Option<Number>, Vec<Number> and HashMap<Number, Vec<Option<Number>>>. e.g.:

fn arbitrary_option_number(u: &mut Unstructured) -> arbitrary::Result<Option<Number>>;
fn arbitrary_vec_number(u: &mut Unstructured) -> arbitrary::Result<Vec<Number>>;
fn arbitrary_hash_map_of_numbers(u: &mut Unstructured) -> arbitrary::Result<HashMap<Number, Vec<Option<Number>>>>;

But this becomes tedious very quickly.

History of the crate

Initially the crate was created to workaround this Arbitrary issue but it was later addressed in this PR.

Dependencies

~0.4–0.8MB
~19K SLoC