use crate::{
generate::Generate, primitive::Constant, shrink::Shrink, state::State, utility::tuples,
};
use core::marker::PhantomData;
#[derive(Debug)]
pub struct Unify<T: ?Sized, I: ?Sized>(pub(crate) PhantomData<I>, pub(crate) T);
impl<T: Clone, I: ?Sized> Clone for Unify<T, I> {
fn clone(&self) -> Self {
Self(PhantomData, self.1.clone())
}
}
impl<G: Generate + ?Sized, I> Generate for Unify<G, I>
where
Unify<G::Shrink, I>: Shrink<Item = I>,
{
type Item = I;
type Shrink = Unify<G::Shrink, I>;
const CARDINALITY: Option<u128> = G::CARDINALITY;
fn generate(&self, state: &mut State) -> Self::Shrink {
Unify(PhantomData, self.1.generate(state))
}
fn cardinality(&self) -> Option<u128> {
self.1.cardinality()
}
}
impl<C: Constant, I> Constant for Unify<C, I> {
const VALUE: Self = Self(PhantomData, C::VALUE);
}
macro_rules! tuple {
($n:ident, $c:tt) => {};
($n:ident, $c:tt $(, $ps:ident, $ts:ident, $is:tt)+) => {
impl<I, $($ts: Shrink<Item: Into<I>>,)*> Shrink for Unify<orn::$n::Or<$($ts,)*>, I> {
type Item = I;
fn item(&self) -> Self::Item {
self.1.item().into()
}
fn shrink(&mut self) -> Option<Self> {
Some(Unify(PhantomData, self.1.shrink()?))
}
}
}
}
tuples!(tuple);