mod display;
mod from_into;
mod limit;
pub use self::{display::*, from_into::*, limit::*};
use core::{hash::Hash, marker::PhantomData};
use arbitrary::{Arbitrary, MaxRecursionReached, Result, Unstructured};
use impl_tools::autoimpl;
use crate::ArbitraryAs;
pub struct As<T: ?Sized>(PhantomData<T>);
impl<T: ?Sized> As<T> {
#[inline]
pub fn arbitrary<'a, U>(u: &mut Unstructured<'a>) -> Result<U>
where
T: ArbitraryAs<'a, U>,
{
T::arbitrary_as(u)
}
}
#[autoimpl(Clone where T: Clone)]
#[autoimpl(Copy where T: Copy)]
#[autoimpl(PartialOrd where T: PartialOrd)]
#[autoimpl(Ord where T: Ord)]
#[autoimpl(PartialEq where T: PartialEq)]
#[autoimpl(Eq where T: Eq)]
#[autoimpl(Hash where T: Hash)]
#[repr(transparent)]
pub struct AsWrap<T, As>
where
As: ?Sized,
{
value: T,
_phantom: PhantomData<As>,
}
impl<T, As> AsWrap<T, As>
where
As: ?Sized,
{
#[inline]
pub const fn new(value: T) -> Self {
Self {
value,
_phantom: PhantomData,
}
}
pub fn from_slice(slice: &[T]) -> &[Self] {
unsafe { slice.as_ptr().cast::<&[Self]>().read() }
}
#[inline]
pub fn into_inner(self) -> T {
self.value
}
}
impl<'a, T, As> Arbitrary<'a> for AsWrap<T, As>
where
As: ArbitraryAs<'a, T> + ?Sized,
{
#[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
As::arbitrary_as(u).map(Self::new)
}
#[inline]
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
As::arbitrary_take_rest_as(u).map(Self::new)
}
#[inline]
fn size_hint(depth: usize) -> (usize, Option<usize>) {
As::size_hint_as(depth)
}
#[inline]
fn try_size_hint(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
As::try_size_hint_as(depth)
}
}
pub struct Same;
impl<'a, T> ArbitraryAs<'a, T> for Same
where
T: Arbitrary<'a>,
{
#[inline]
fn arbitrary_as(u: &mut Unstructured<'a>) -> Result<T> {
T::arbitrary(u)
}
#[inline]
fn arbitrary_take_rest_as(u: Unstructured<'a>) -> Result<T> {
T::arbitrary_take_rest(u)
}
#[inline]
fn size_hint_as(depth: usize) -> (usize, Option<usize>) {
T::size_hint(depth)
}
#[inline]
fn try_size_hint_as(depth: usize) -> Result<(usize, Option<usize>), MaxRecursionReached> {
T::try_size_hint(depth)
}
}