#![deny(bad_style)]
#![deny(missing_docs)]
#![deny(future_incompatible)]
#![deny(nonstandard_style)]
#![deny(rust_2018_compatibility)]
#![deny(rust_2018_idioms)]
#![deny(unused)]
#[cfg(feature = "derive_arbitrary")]
pub use derive_arbitrary::*;
mod error;
pub use error::*;
pub mod unstructured;
#[doc(inline)]
pub use unstructured::Unstructured;
pub mod size_hint;
use core::cell::{Cell, RefCell, UnsafeCell};
use core::iter;
use core::mem;
use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
use core::str;
use core::time::Duration;
use std::borrow::{Cow, ToOwned};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
use std::ffi::{CString, OsString};
use std::path::PathBuf;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
use std::sync::{Arc, Mutex};
pub trait Arbitrary<'a>: Sized {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>;
fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
Self::arbitrary(&mut u)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
let _ = depth;
(0, None)
}
}
impl<'a> Arbitrary<'a> for () {
fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
Ok(())
}
#[inline]
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl<'a> Arbitrary<'a> for bool {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(<u8 as Arbitrary<'a>>::arbitrary(u)? & 1 == 1)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<u8 as Arbitrary<'a>>::size_hint(depth)
}
}
macro_rules! impl_arbitrary_for_integers {
( $( $ty:ty: $unsigned:ty; )* ) => {
$(
impl<'a> Arbitrary<'a> for $ty {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let mut buf = [0; mem::size_of::<$ty>()];
u.fill_buffer(&mut buf)?;
let mut x: $unsigned = 0;
for i in 0..mem::size_of::<$ty>() {
x |= buf[i] as $unsigned << (i * 8);
}
Ok(x as $ty)
}
#[inline]
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
let n = mem::size_of::<$ty>();
(n, Some(n))
}
}
)*
}
}
impl_arbitrary_for_integers! {
u8: u8;
u16: u16;
u32: u32;
u64: u64;
u128: u128;
usize: usize;
i8: u8;
i16: u16;
i32: u32;
i64: u64;
i128: u128;
isize: usize;
}
macro_rules! impl_arbitrary_for_floats {
( $( $ty:ident : $unsigned:ty; )* ) => {
$(
impl<'a> Arbitrary<'a> for $ty {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<$unsigned as Arbitrary<'a>>::size_hint(depth)
}
}
)*
}
}
impl_arbitrary_for_floats! {
f32: u32;
f64: u64;
}
impl<'a> Arbitrary<'a> for char {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
use std::char;
const CHAR_END: u32 = 0x0011_000;
const SURROGATES_START: u32 = 0xD800;
let mut c = <u32 as Arbitrary<'a>>::arbitrary(u)? % CHAR_END;
if let Some(c) = char::from_u32(c) {
return Ok(c);
} else {
c -= SURROGATES_START;
Ok(char::from_u32(c)
.expect("Generated character should be valid! This is a bug in arbitrary-rs"))
}
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<u32 as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for AtomicBool {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<bool as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for AtomicIsize {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<isize as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for AtomicUsize {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<usize as Arbitrary<'a>>::size_hint(depth)
}
}
macro_rules! impl_range {
(
$range:ty,
$value_closure:expr,
$value_ty:ty,
$fun:ident($fun_closure:expr),
$size_hint_closure:expr
) => {
impl<'a, A> Arbitrary<'a> for $range
where
A: Arbitrary<'a> + Clone + PartialOrd,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let value: $value_ty = Arbitrary::arbitrary(u)?;
Ok($fun(value, $fun_closure))
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
$size_hint_closure(depth)
}
}
};
}
impl_range!(
Range<A>,
|r: &Range<A>| (r.start.clone(), r.end.clone()),
(A, A),
bounded_range(|(a, b)| a..b),
|depth| crate::size_hint::and(
<A as Arbitrary>::size_hint(depth),
<A as Arbitrary>::size_hint(depth)
)
);
impl_range!(
RangeFrom<A>,
|r: &RangeFrom<A>| r.start.clone(),
A,
unbounded_range(|a| a..),
|depth| <A as Arbitrary>::size_hint(depth)
);
impl_range!(
RangeInclusive<A>,
|r: &RangeInclusive<A>| (r.start().clone(), r.end().clone()),
(A, A),
bounded_range(|(a, b)| a..=b),
|depth| crate::size_hint::and(
<A as Arbitrary>::size_hint(depth),
<A as Arbitrary>::size_hint(depth)
)
);
impl_range!(
RangeTo<A>,
|r: &RangeTo<A>| r.end.clone(),
A,
unbounded_range(|b| ..b),
|depth| <A as Arbitrary>::size_hint(depth)
);
impl_range!(
RangeToInclusive<A>,
|r: &RangeToInclusive<A>| r.end.clone(),
A,
unbounded_range(|b| ..=b),
|depth| <A as Arbitrary>::size_hint(depth)
);
pub(crate) fn bounded_range<CB, I, R>(bounds: (I, I), cb: CB) -> R
where
CB: Fn((I, I)) -> R,
I: PartialOrd,
R: RangeBounds<I>,
{
let (mut start, mut end) = bounds;
if start > end {
mem::swap(&mut start, &mut end);
}
cb((start, end))
}
pub(crate) fn unbounded_range<CB, I, R>(bound: I, cb: CB) -> R
where
CB: Fn(I) -> R,
R: RangeBounds<I>,
{
cb(bound)
}
impl<'a> Arbitrary<'a> for Duration {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(Self::new(
<u64 as Arbitrary>::arbitrary(u)?,
u.int_in_range(0..=999_999_999)?,
))
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(
<u64 as Arbitrary>::size_hint(depth),
<u32 as Arbitrary>::size_hint(depth),
)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Option<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
Some(Arbitrary::arbitrary(u)?)
} else {
None
})
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(
<bool as Arbitrary>::size_hint(depth),
crate::size_hint::or((0, Some(0)), <A as Arbitrary>::size_hint(depth)),
)
}
}
impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for std::result::Result<A, B> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
Ok(<A as Arbitrary>::arbitrary(u)?)
} else {
Err(<B as Arbitrary>::arbitrary(u)?)
})
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(
<bool as Arbitrary>::size_hint(depth),
crate::size_hint::or(
<A as Arbitrary>::size_hint(depth),
<B as Arbitrary>::size_hint(depth),
),
)
}
}
macro_rules! arbitrary_tuple {
() => {};
($last: ident $($xs: ident)*) => {
arbitrary_tuple!($($xs)*);
impl<'a, $($xs: Arbitrary<'a>,)* $last: Arbitrary<'a>> Arbitrary<'a> for ($($xs,)* $last,) {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Ok(($($xs::arbitrary(u)?,)* Arbitrary::arbitrary(u)?,))
}
#[allow(unused_mut, non_snake_case)]
fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
$(let $xs = $xs::arbitrary(&mut u)?;)*
let $last = $last::arbitrary_take_rest(u)?;
Ok(($($xs,)* $last,))
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and_all(&[
<$last as Arbitrary>::size_hint(depth),
$( <$xs as Arbitrary>::size_hint(depth) ),*
])
}
}
};
}
arbitrary_tuple!(A 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);
macro_rules! arbitrary_array {
{$n:expr, ($t:ident, $a:ident) $(($ts:ident, $as:ident))*} => {
arbitrary_array!{($n - 1), $(($ts, $as))*}
impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; $n] {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<[T; $n]> {
Ok([
Arbitrary::arbitrary(u)?,
$(<$ts as Arbitrary>::arbitrary(u)?),*
])
}
#[allow(unused_mut)]
fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<[T; $n]> {
$(let $as = $ts::arbitrary(&mut u)?;)*
let last = Arbitrary::arbitrary_take_rest(u)?;
Ok([
$($as,)* last
])
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and_all(&[
<$t as Arbitrary>::size_hint(depth),
$( <$ts as Arbitrary>::size_hint(depth) ),*
])
}
}
};
($n: expr,) => {};
}
impl<'a, T: Arbitrary<'a>> Arbitrary<'a> for [T; 0] {
fn arbitrary(_: &mut Unstructured<'a>) -> Result<[T; 0]> {
Ok([])
}
fn arbitrary_take_rest(_: Unstructured<'a>) -> Result<[T; 0]> {
Ok([])
}
#[inline]
fn size_hint(_: usize) -> (usize, Option<usize>) {
crate::size_hint::and_all(&[])
}
}
arbitrary_array! { 32, (T, a) (T, b) (T, c) (T, d) (T, e) (T, f) (T, g) (T, h)
(T, i) (T, j) (T, k) (T, l) (T, m) (T, n) (T, o) (T, p)
(T, q) (T, r) (T, s) (T, u) (T, v) (T, w) (T, x) (T, y)
(T, z) (T, aa) (T, ab) (T, ac) (T, ad) (T, ae) (T, af)
(T, ag) }
impl<'a> Arbitrary<'a> for &'a [u8] {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let len = u.arbitrary_len::<u8>()?;
u.bytes(len)
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
Ok(u.take_rest())
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<usize as Arbitrary>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap<K, V> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BTreeSet<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>> Arbitrary<'a>
for HashMap<K, V>
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash> Arbitrary<'a> for HashSet<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
u.arbitrary_iter()?.collect()
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
u.arbitrary_take_rest_iter()?.collect()
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a, A> Arbitrary<'a> for Cow<'a, A>
where
A: ToOwned + ?Sized,
<A as ToOwned>::Owned: Arbitrary<'a>,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Cow::Owned)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::recursion_guard(depth, |depth| {
<<A as ToOwned>::Owned as Arbitrary>::size_hint(depth)
})
}
}
impl<'a> Arbitrary<'a> for &'a str {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
let size = u.arbitrary_len::<u8>()?;
match str::from_utf8(&u.peek_bytes(size).unwrap()) {
Ok(s) => {
u.bytes(size).unwrap();
Ok(s)
}
Err(e) => {
let i = e.valid_up_to();
let valid = u.bytes(i).unwrap();
let s = unsafe {
debug_assert!(str::from_utf8(valid).is_ok());
str::from_utf8_unchecked(valid)
};
Ok(s)
}
}
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
let bytes = u.take_rest();
str::from_utf8(bytes)
.map_err(|_| Error::IncorrectFormat)
.map(Into::into)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::and(<usize as Arbitrary>::size_hint(depth), (0, None))
}
}
impl<'a> Arbitrary<'a> for String {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<&str as Arbitrary>::arbitrary(u).map(Into::into)
}
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
<&str as Arbitrary>::arbitrary_take_rest(u).map(Into::into)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<&str as Arbitrary>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for CString {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<Vec<u8> as Arbitrary>::arbitrary(u).map(|mut x| {
x.retain(|&c| c != 0);
Self::new(x).unwrap()
})
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<Vec<u8> as Arbitrary>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for OsString {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<String as Arbitrary>::arbitrary(u).map(From::from)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<String as Arbitrary>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for PathBuf {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<OsString as Arbitrary>::arbitrary(u).map(From::from)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<OsString as Arbitrary>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<Vec<A> as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_slice())
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<Vec<A> as Arbitrary>::size_hint(depth)
}
}
impl<'a> Arbitrary<'a> for Box<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<String as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_str())
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<String as Arbitrary>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
crate::size_hint::recursion_guard(depth, |depth| <A as Arbitrary>::size_hint(depth))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Cell<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<A as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for RefCell<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<A as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for UnsafeCell<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<A as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Mutex<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<A as Arbitrary<'a>>::size_hint(depth)
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for iter::Empty<A> {
fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
Ok(iter::empty())
}
#[inline]
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::marker::PhantomData<A> {
fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
Ok(::std::marker::PhantomData)
}
#[inline]
fn size_hint(_depth: usize) -> (usize, Option<usize>) {
(0, Some(0))
}
}
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::num::Wrapping<A> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(::std::num::Wrapping)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<A as Arbitrary<'a>>::size_hint(depth)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn finite_buffer_fill_buffer() {
let x = [1, 2, 3, 4];
let mut rb = Unstructured::new(&x);
let mut z = [0; 2];
rb.fill_buffer(&mut z).unwrap();
assert_eq!(z, [1, 2]);
rb.fill_buffer(&mut z).unwrap();
assert_eq!(z, [3, 4]);
rb.fill_buffer(&mut z).unwrap();
assert_eq!(z, [0, 0]);
}
#[test]
fn arbitrary_for_integers() {
let x = [1, 2, 3, 4];
let mut buf = Unstructured::new(&x);
let expected = 1 | (2 << 8) | (3 << 16) | (4 << 24);
let actual = i32::arbitrary(&mut buf).unwrap();
assert_eq!(expected, actual);
}
#[test]
fn arbitrary_for_bytes() {
let x = [1, 2, 3, 4, 4];
let mut buf = Unstructured::new(&x);
let expected = &[1, 2, 3, 4];
let actual = <&[u8] as Arbitrary>::arbitrary(&mut buf).unwrap();
assert_eq!(expected, actual);
}
#[test]
fn arbitrary_take_rest_for_bytes() {
let x = [1, 2, 3, 4];
let buf = Unstructured::new(&x);
let expected = &[1, 2, 3, 4];
let actual = <&[u8] as Arbitrary>::arbitrary_take_rest(buf).unwrap();
assert_eq!(expected, actual);
}
#[test]
fn arbitrary_collection() {
let x = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8,
];
assert_eq!(
Vec::<u8>::arbitrary(&mut Unstructured::new(&x)).unwrap(),
&[2, 4, 6, 8, 1]
);
assert_eq!(
Vec::<u32>::arbitrary(&mut Unstructured::new(&x)).unwrap(),
&[84148994]
);
assert_eq!(
String::arbitrary(&mut Unstructured::new(&x)).unwrap(),
"\x01\x02\x03\x04\x05\x06\x07\x08"
);
}
#[test]
fn arbitrary_take_rest() {
let x = [1, 2, 3, 4];
assert_eq!(
Vec::<u8>::arbitrary_take_rest(Unstructured::new(&x)).unwrap(),
&[1, 2, 3, 4]
);
assert_eq!(
Vec::<u32>::arbitrary_take_rest(Unstructured::new(&x)).unwrap(),
&[0x4030201]
);
assert_eq!(
String::arbitrary_take_rest(Unstructured::new(&x)).unwrap(),
"\x01\x02\x03\x04"
);
}
#[test]
fn size_hint_for_tuples() {
assert_eq!(
(7, Some(7)),
<(bool, u16, i32) as Arbitrary<'_>>::size_hint(0)
);
assert_eq!(
(1 + mem::size_of::<usize>(), None),
<(u8, Vec<u8>) as Arbitrary>::size_hint(0)
);
}
}