pbt 0.4.22

Property-based testing with `derive` macros, aware of mutual induction & instantiability.
Documentation
//! Shape traits used by field-wise interfaces generated by `#[derive(Pbt)]`.
//!
//! These traits witness lossless equivalence to canonical field shapes. Literal
//! shapes use bidirectional owned conversion; container shapes use owned
//! conversion to and from their canonical container with shaped parameters.

use {
    alloc::{boxed::Box, ffi::CString, rc::Rc, string::String, sync::Arc, vec::Vec},
    core::{convert::Infallible, marker::PhantomData, num::NonZero},
};

/// Implement [`NonZeroShaped`] for one canonical nonzero primitive.
macro_rules! impl_nonzero_shaped {
    ($item:ty) => {
        impl<This> NonZeroShaped<$item> for This
        where
            This: From<NonZero<$item>> + Into<NonZero<$item>>,
        {
            type Canonical = NonZero<$item>;

            #[inline(always)]
            fn from_nonzero(nonzero: Self::Canonical) -> Self {
                nonzero.into()
            }

            #[inline(always)]
            fn into_nonzero(self) -> Self::Canonical {
                self.into()
            }
        }
    };
}

/// Shape equivalent to `Arc<Item>`.
pub trait ArcShaped<Item>: From<Arc<Item>> + Into<Arc<Item>> {}

impl<Item, This> ArcShaped<Item> for This where This: From<Arc<Item>> + Into<Arc<Item>> {}

/// Shape equivalent to `bool`.
pub trait BoolShaped: From<bool> + Into<bool> {}

impl<This> BoolShaped for This where This: From<bool> + Into<bool> {}

/// Shape equivalent to `Box<Item>`.
pub trait BoxShaped<Item>: From<Box<Item>> + Into<Box<Item>> {}

impl<Item, This> BoxShaped<Item> for This where This: From<Box<Item>> + Into<Box<Item>> {}

/// Shape equivalent to `char`.
pub trait CharShaped: From<char> + Into<char> {}

impl<This> CharShaped for This where This: From<char> + Into<char> {}

/// Shape equivalent to `CString`.
pub trait CStringShaped: From<CString> + Into<CString> {}

impl<This> CStringShaped for This where This: From<CString> + Into<CString> {}

/// Shape equivalent to `i8`.
pub trait I8Shaped: From<i8> + Into<i8> {}

impl<This> I8Shaped for This where This: From<i8> + Into<i8> {}

/// Shape equivalent to `i16`.
pub trait I16Shaped: From<i16> + Into<i16> {}

impl<This> I16Shaped for This where This: From<i16> + Into<i16> {}

/// Shape equivalent to `i32`.
pub trait I32Shaped: From<i32> + Into<i32> {}

impl<This> I32Shaped for This where This: From<i32> + Into<i32> {}

/// Shape equivalent to `i64`.
pub trait I64Shaped: From<i64> + Into<i64> {}

impl<This> I64Shaped for This where This: From<i64> + Into<i64> {}

/// Shape equivalent to `i128`.
pub trait I128Shaped: From<i128> + Into<i128> {}

impl<This> I128Shaped for This where This: From<i128> + Into<i128> {}

/// Shape equivalent to `Infallible`.
pub trait InfallibleShaped: From<Infallible> + Into<Infallible> {}

impl<This> InfallibleShaped for This where This: From<Infallible> + Into<Infallible> {}

/// Shape equivalent to `isize`.
pub trait IsizeShaped: From<isize> + Into<isize> {}

impl<This> IsizeShaped for This where This: From<isize> + Into<isize> {}

/// Shape equivalent to a nonzero value whose underlying item has shape `Item`.
pub trait NonZeroShaped<Item> {
    /// The canonical nonzero shape for this implementation.
    type Canonical;

    /// Convert from the canonical nonzero shape.
    fn from_nonzero(nonzero: Self::Canonical) -> Self;

    /// Convert into the canonical nonzero shape.
    fn into_nonzero(self) -> Self::Canonical;
}

impl_nonzero_shaped!(u8);
impl_nonzero_shaped!(u16);
impl_nonzero_shaped!(u32);
impl_nonzero_shaped!(u64);
impl_nonzero_shaped!(u128);
impl_nonzero_shaped!(usize);
impl_nonzero_shaped!(i8);
impl_nonzero_shaped!(i16);
impl_nonzero_shaped!(i32);
impl_nonzero_shaped!(i64);
impl_nonzero_shaped!(i128);
impl_nonzero_shaped!(isize);
impl_nonzero_shaped!(char);

/// Shape equivalent to `Option<Item>`.
pub trait OptionShaped<Item>: From<Option<Item>> + Into<Option<Item>> {}

impl<Item, This> OptionShaped<Item> for This where This: From<Option<Item>> + Into<Option<Item>> {}

/// Shape equivalent to `PhantomData<Item>`.
pub trait PhantomDataShaped<Item>: From<PhantomData<Item>> + Into<PhantomData<Item>> {}

impl<Item, This> PhantomDataShaped<Item> for This where
    This: From<PhantomData<Item>> + Into<PhantomData<Item>>
{
}

/// Shape equivalent to `Rc<Item>`.
pub trait RcShaped<Item>: From<Rc<Item>> + Into<Rc<Item>> {}

impl<Item, This> RcShaped<Item> for This where This: From<Rc<Item>> + Into<Rc<Item>> {}

/// Shape equivalent to `String`.
pub trait StringShaped: From<String> + Into<String> {}

impl<This> StringShaped for This where This: From<String> + Into<String> {}

/// Shape equivalent to `u8`.
pub trait U8Shaped: From<u8> + Into<u8> {}

impl<This> U8Shaped for This where This: From<u8> + Into<u8> {}

/// Shape equivalent to `u16`.
pub trait U16Shaped: From<u16> + Into<u16> {}

impl<This> U16Shaped for This where This: From<u16> + Into<u16> {}

/// Shape equivalent to `u32`.
pub trait U32Shaped: From<u32> + Into<u32> {}

impl<This> U32Shaped for This where This: From<u32> + Into<u32> {}

/// Shape equivalent to `u64`.
pub trait U64Shaped: From<u64> + Into<u64> {}

impl<This> U64Shaped for This where This: From<u64> + Into<u64> {}

/// Shape equivalent to `u128`.
pub trait U128Shaped: From<u128> + Into<u128> {}

impl<This> U128Shaped for This where This: From<u128> + Into<u128> {}

/// Shape equivalent to `usize`.
pub trait UsizeShaped: From<usize> + Into<usize> {}

impl<This> UsizeShaped for This where This: From<usize> + Into<usize> {}

/// Shape equivalent to `Vec<Item>`.
pub trait VecShaped<Item>: From<Vec<Item>> + Into<Vec<Item>> {}

impl<Item, This> VecShaped<Item> for This where This: From<Vec<Item>> + Into<Vec<Item>> {}