# bolero-generator value generator for testing and fuzzing ## Installation `bolero-generator` is on `crates.io` and can be added to a project like so: ```sh $ cargo add --dev bolero-generator ``` ## Usage ### Simple type generator ```rust use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator}; let input = &[1, 2, 3, 4, 5]; let driver = FuzzDriver::new(&input); let value = gen::().generate(&mut driver).unwrap(); ``` ### Parameterized value generator ```rust use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator}; let input = &[1, 2, 3, 4, 5]; let driver = FuzzDriver::new(&input); let value = gen::().with().bounds(5..=42).generate(&mut driver).unwrap(); ``` ### Nested parameterized value generator ```rust use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator}; let input = &[1, 2, 3, 4, 5]; let driver = FuzzDriver::new(&input); let value = ( gen::(), gen::() .with() .bounds(5..=42), // between 5 and including 42 gen::>() .with() .len(6usize) // always have 6 values .values(7..500), // between 7 and 500 ).generate(&mut driver).unwrap(); ``` ### Value modifications with `map` and `and_then` ```rust use bolero_generator::{gen, driver::FuzzDriver, ValueGenerator}; let input = &[1, 2, 3, 4, 5]; let driver = FuzzDriver::new(&input); let value = gen::() .map(|value| value / 2) .and_then(|value| gen::>().with().len(value as usize)) .generate(&mut driver) .unwrap() ``` ## Prior work ### [arbitrary](https://github.com/nagisa/rust_arbitrary) While `bolero` draws a lot of inspiration from the `rust_arbitrary` crate, several improvements were added: #### Parameterized generation Arbitrary supports basic value generation, given a type: ```rust let driver = RingBuffer::new(input, 20).unwrap(); let value: u8 = Arbitrary::arbitrary(&mut driver).unwrap(); ``` This can be limiting when constraints need to be applied to the type: ```rust let driver = RingBuffer::new(input, 20).unwrap(); let value: u8 = Arbitrary::arbitrary(&mut driver).unwrap(); // make sure `value` in between 8 and 20 let value = (value % (20 - 8)) + 8; ``` The same issue arises from [container sizes](https://github.com/nagisa/rust_arbitrary/blob/f077e8c4017dab7e6d9ea4c5148b6b19b0588ecd/src/lib.rs#L42) being limited to 0-255: ```rust let driver = RingBuffer::new(input, 20).unwrap(); let mut value: Vec = Arbitrary::arbitrary(&mut driver).unwrap(); // make sure `value` has at least 3 items while value.len() < 3 { value.push(Arbitrary::arbitrary(&mut driver).unwrap()); } // make sure `value` has no more than 42 items while value.len() > 42 { value.pop(); } ``` `bolero` supports value generation, given a type: ```rust let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]); let value = gen::().generate(&mut driver).unwrap(); ``` Parameterized generators can be created by calling `with()` ```rust let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]); let value = gen::().with().bounds(8..=20).generate(&mut driver).unwrap(); ``` Container sizes can be specified as well: ```rust let driver = FuzzDriver::new(&[1, 2, 3, 4, 5]); let value = gen::>().with().len(3usize..=42).generate(&mut driver).unwrap(); ``` #### `#![no_std]` compatibility `bolero` supports environments that require `#![no_std]`.