Skip to content

Commit

Permalink
feat: introduce ArbitraryInRange
Browse files Browse the repository at this point in the history
  • Loading branch information
sivizius committed Sep 21, 2024
1 parent 1cc0e46 commit d97bd18
Show file tree
Hide file tree
Showing 26 changed files with 1,053 additions and 768 deletions.
3 changes: 3 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ pub enum Error {
NotEnoughData,
/// The input bytes were not of the right format
IncorrectFormat,
/// Cannot generate value in given range
InvalidRange,
}

impl fmt::Display for Error {
Expand All @@ -28,6 +30,7 @@ impl fmt::Display for Error {
f,
"The raw data is not of the correct format to construct this type"
),
Error::InvalidRange => write!(f, "Cannot generate a value in given range"),
}
}
}
Expand Down
40 changes: 3 additions & 37 deletions src/foreign/alloc/boxed.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
use {
crate::{size_hint, Arbitrary, Result, Unstructured},
crate::{Arbitrary, Result, Unstructured},
std::boxed::Box,
};

impl<'a, A> Arbitrary<'a> for Box<A>
where
A: Arbitrary<'a>,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
Self::try_size_hint(depth).unwrap_or_default()
}

#[inline]
fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), crate::MaxRecursionReached> {
size_hint::try_recursion_guard(depth, <A as Arbitrary>::try_size_hint)
}
}

impl<'a, A> Arbitrary<'a> for Box<[A]>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_wrapped_new! { Box! }
implement_from_iter! { Box<[A]> }

impl<'a> Arbitrary<'a> for Box<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Expand Down
23 changes: 2 additions & 21 deletions src/foreign/alloc/collections/binary_heap.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::collections::binary_heap::BinaryHeap,
};
use std::collections::binary_heap::BinaryHeap;

impl<'a, A> Arbitrary<'a> for BinaryHeap<A>
where
A: Arbitrary<'a> + Ord,
{
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>) {
(0, None)
}
}
implement_from_iter! { BinaryHeap<A>: Ord }
23 changes: 2 additions & 21 deletions src/foreign/alloc/collections/btree_set.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::collections::btree_set::BTreeSet,
};
use std::collections::btree_set::BTreeSet;

impl<'a, A> Arbitrary<'a> for BTreeSet<A>
where
A: Arbitrary<'a> + Ord,
{
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>) {
(0, None)
}
}
implement_from_iter! { BTreeSet<A>: Ord }
23 changes: 2 additions & 21 deletions src/foreign/alloc/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::collections::linked_list::LinkedList,
};
use std::collections::linked_list::LinkedList;

impl<'a, A> Arbitrary<'a> for LinkedList<A>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_from_iter! { LinkedList<A> }
23 changes: 2 additions & 21 deletions src/foreign/alloc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::collections::vec_deque::VecDeque,
};
use std::collections::vec_deque::VecDeque;

impl<'a, A> Arbitrary<'a> for VecDeque<A>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_from_iter! { VecDeque<A> }
40 changes: 3 additions & 37 deletions src/foreign/alloc/rc.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
use {
crate::{size_hint, Arbitrary, Result, Unstructured},
crate::{Arbitrary, Result, Unstructured},
std::rc::Rc,
};

impl<'a, A> Arbitrary<'a> for Rc<A>
where
A: Arbitrary<'a>,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
Self::try_size_hint(depth).unwrap_or_default()
}

#[inline]
fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), crate::MaxRecursionReached> {
size_hint::try_recursion_guard(depth, <A as Arbitrary>::try_size_hint)
}
}

impl<'a, A> Arbitrary<'a> for Rc<[A]>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_wrapped_new! { Rc! }
implement_from_iter! { Rc<[A]> }

impl<'a> Arbitrary<'a> for Rc<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Expand Down
16 changes: 14 additions & 2 deletions src/foreign/alloc/string.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::string::String,
crate::{Arbitrary, ArbitraryInRange, Result, Unstructured},
std::{ops::RangeBounds, string::String},
};

impl<'a> ArbitraryInRange<'a> for String {
type Bound = char;

fn arbitrary_in_range<R>(u: &mut Unstructured<'a>, range: &R) -> Result<Self>
where
R: RangeBounds<Self::Bound>,
{
u.arbitrary_in_range_iter::<Self::Bound, _>(range)?
.collect()
}
}

impl<'a> Arbitrary<'a> for String {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<&str as Arbitrary>::arbitrary(u).map(Into::into)
Expand Down
40 changes: 3 additions & 37 deletions src/foreign/alloc/sync.rs
Original file line number Diff line number Diff line change
@@ -1,44 +1,10 @@
use {
crate::{size_hint, Arbitrary, Result, Unstructured},
crate::{Arbitrary, Result, Unstructured},
std::sync::Arc,
};

impl<'a, A> Arbitrary<'a> for Arc<A>
where
A: Arbitrary<'a>,
{
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Arbitrary::arbitrary(u).map(Self::new)
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
Self::try_size_hint(depth).unwrap_or_default()
}

#[inline]
fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), crate::MaxRecursionReached> {
size_hint::try_recursion_guard(depth, <A as Arbitrary>::try_size_hint)
}
}

impl<'a, A> Arbitrary<'a> for Arc<[A]>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_wrapped_new! { Arc! }
implement_from_iter! { Arc<[A]> }

impl<'a> Arbitrary<'a> for Arc<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
Expand Down
23 changes: 2 additions & 21 deletions src/foreign/alloc/vec.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,3 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::vec::Vec,
};
use std::vec::Vec;

impl<'a, A> Arbitrary<'a> for Vec<A>
where
A: Arbitrary<'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>) {
(0, None)
}
}
implement_from_iter! { Vec<A> }
35 changes: 31 additions & 4 deletions src/foreign/core/array.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use {
crate::{size_hint, Arbitrary, Result, Unstructured},
crate::{size_hint, Arbitrary, ArbitraryInRange, Result, Unstructured},
core::{
array,
mem::{self, MaybeUninit},
Expand Down Expand Up @@ -45,20 +45,47 @@ where
}
}

impl<'a, T, const N: usize> ArbitraryInRange<'a> for [T; N]
where
T: ArbitraryInRange<'a>,
{
type Bound = T::Bound;

#[inline]
fn arbitrary_in_range<R>(u: &mut Unstructured<'a>, range: &R) -> Result<Self>
where
R: std::ops::RangeBounds<Self::Bound>,
{
try_create_array(|_| T::arbitrary_in_range(u, range))
}

#[inline]
fn arbitrary_in_range_take_rest<R>(mut u: Unstructured<'a>, range: &R) -> Result<Self>
where
R: std::ops::RangeBounds<Self::Bound>,
{
let mut array = Self::arbitrary_in_range(&mut u, range)?;
if let Some(last) = array.last_mut() {
*last = T::arbitrary_in_range_take_rest(u, range)?;
}
Ok(array)
}
}

impl<'a, T, const N: usize> Arbitrary<'a> for [T; N]
where
T: Arbitrary<'a>,
{
#[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
try_create_array(|_| <T as Arbitrary<'a>>::arbitrary(u))
try_create_array(|_| T::arbitrary(u))
}

#[inline]
fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
let mut array = Self::arbitrary(&mut u)?;
if let Some(last) = array.last_mut() {
*last = Arbitrary::arbitrary_take_rest(u)?;
*last = T::arbitrary_take_rest(u)?;
}
Ok(array)
}
Expand All @@ -70,7 +97,7 @@ where

#[inline]
fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), crate::MaxRecursionReached> {
let hint = <T as Arbitrary>::try_size_hint(depth)?;
let hint = T::try_size_hint(depth)?;
Ok(size_hint::and_all(&array::from_fn::<_, N, _>(|_| hint)))
}
}
Loading

0 comments on commit d97bd18

Please sign in to comment.