Skip to content

Commit

Permalink
refactor(foreign): move implementations to dedicated directory
Browse files Browse the repository at this point in the history
At the moment, the trait-definition and all implementations for
foreign types are located in `lib.rs` with 1732 LOC. IMHO this is
difficult to maintain, especially when adding additional
implementations. By moving all implementations into the private
submodule foreign, sorting them by `core`, `alloc` and `std`, and
submodules similar to those documented, I see i.a. the following
advantages:

1. Easier to find for which types the trait is implemented, which
   implementations are missing,
2. If one wants to add a implementation, one can just place it in the
   module according to its type definition in `core`/`alloc`/`std` and
   does not have to guess, whether to place it at the beginning or end
   of `lib.rs` or somewhere random,
3. It will be easier to feature-gate some implementations, e.g. `std`
   for std-implementations, which should be a default-feature, which
   can be disabled for `no_std`-builds,
4. Implementations for additional (common) crates, e.g. `chrono` or
   `time`, can be placed in foreign behind feature-gates,
5. Changes to one file does not affect changes to other files, so
   merging multiple PRs might be less conflicting.

Somewhat unrelated changes: Harmonising trait-bounds-placement.
  • Loading branch information
sivizius committed Aug 22, 2024
1 parent 7bd1044 commit e54d1c7
Show file tree
Hide file tree
Showing 46 changed files with 1,592 additions and 1,339 deletions.
21 changes: 21 additions & 0 deletions src/foreign/alloc/borrow.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use {
crate::{size_hint, Arbitrary, Result, Unstructured},
std::borrow::{Cow, ToOwned},
};

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>) {
size_hint::recursion_guard(depth, |depth| {
<<A as ToOwned>::Owned as Arbitrary>::size_hint(depth)
})
}
}
47 changes: 47 additions & 0 deletions src/foreign/alloc/boxed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use {
crate::{size_hint, 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>) {
size_hint::recursion_guard(depth, <A as Arbitrary>::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)
}
}

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)
}
}
22 changes: 22 additions & 0 deletions src/foreign/alloc/collections/binary_heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
crate::{Arbitrary, Result, Unstructured},
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)
}
}
23 changes: 23 additions & 0 deletions src/foreign/alloc/collections/btree_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::collections::btree_map::BTreeMap,
};

impl<'a, K, V> Arbitrary<'a> for BTreeMap<K, V>
where
K: Arbitrary<'a> + Ord,
V: 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)
}
}
22 changes: 22 additions & 0 deletions src/foreign/alloc/collections/btree_set.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
crate::{Arbitrary, Result, Unstructured},
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)
}
}
22 changes: 22 additions & 0 deletions src/foreign/alloc/collections/linked_list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
crate::{Arbitrary, Result, Unstructured},
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)
}
}
5 changes: 5 additions & 0 deletions src/foreign/alloc/collections/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
mod binary_heap;
mod btree_map;
mod btree_set;
mod linked_list;
mod vec_deque;
22 changes: 22 additions & 0 deletions src/foreign/alloc/collections/vec_deque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
crate::{Arbitrary, Result, Unstructured},
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)
}
}
19 changes: 19 additions & 0 deletions src/foreign/alloc/ffi/c_str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::ffi::CString,
};

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);
// SAFETY: all zero bytes have been removed
unsafe { Self::from_vec_unchecked(x) }
})
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<Vec<u8> as Arbitrary>::size_hint(depth)
}
}
1 change: 1 addition & 0 deletions src/foreign/alloc/ffi/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
mod c_str;
13 changes: 13 additions & 0 deletions src/foreign/alloc/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! Implementations of [`Arbitrary`] for [`alloc`] types,
//! excluding those in [`core`].
//!
//! [`Arbitrary`]: crate::Arbitrary

mod borrow;
mod boxed;
mod collections;
mod ffi;
mod rc;
mod string;
mod sync;
mod vec;
47 changes: 47 additions & 0 deletions src/foreign/alloc/rc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use {
crate::{size_hint, 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>) {
size_hint::recursion_guard(depth, <A as Arbitrary>::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)
}
}

impl<'a> Arbitrary<'a> for Rc<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<&str as Arbitrary>::arbitrary(u).map(Into::into)
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<&str as Arbitrary>::size_hint(depth)
}
}
19 changes: 19 additions & 0 deletions src/foreign/alloc/string.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use {
crate::{Arbitrary, Result, Unstructured},
std::string::String,
};

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)
}
}
47 changes: 47 additions & 0 deletions src/foreign/alloc/sync.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
use {
crate::{size_hint, 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>) {
size_hint::recursion_guard(depth, <A as Arbitrary>::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)
}
}

impl<'a> Arbitrary<'a> for Arc<str> {
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
<&str as Arbitrary>::arbitrary(u).map(Into::into)
}

#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
<&str as Arbitrary>::size_hint(depth)
}
}
22 changes: 22 additions & 0 deletions src/foreign/alloc/vec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use {
crate::{Arbitrary, Result, Unstructured},
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)
}
}
Loading

0 comments on commit e54d1c7

Please sign in to comment.