Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: introduce ArbitraryInRange #192

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading