use crate::std_facade::fmt;
use crate::strategy::{Strategy, BoxedStrategy};
pub trait ArbitraryF1<A: fmt::Debug>: fmt::Debug + Sized {
type Parameters: Default;
fn lift1<AS>(base: AS) -> BoxedStrategy<Self>
where AS: Strategy<Value = A> + 'static {
Self::lift1_with(base, Self::Parameters::default())
}
fn lift1_with<AS>(base: AS, args: Self::Parameters) -> BoxedStrategy<Self>
where AS: Strategy<Value = A> + 'static;
}
pub trait ArbitraryF2<A: fmt::Debug, B: fmt::Debug>: fmt::Debug + Sized {
type Parameters: Default;
fn lift2<AS, BS>(fst: AS, snd: BS) -> BoxedStrategy<Self>
where
AS: Strategy<Value = A> + 'static,
BS: Strategy<Value = B> + 'static,
{
Self::lift2_with(fst, snd, Self::Parameters::default())
}
fn lift2_with<AS, BS>(fst: AS, snd: BS, args: Self::Parameters)
-> BoxedStrategy<Self>
where
AS: Strategy<Value = A> + 'static,
BS: Strategy<Value = B> + 'static;
}
macro_rules! lift1 {
([$($bounds : tt)*] $typ: ty, $params: ty;
$base: ident, $args: ident => $logic: expr) => {
impl<A: ::core::fmt::Debug + $($bounds)*>
$crate::arbitrary::functor::ArbitraryF1<A>
for $typ {
type Parameters = $params;
fn lift1_with<S>($base: S, $args: Self::Parameters)
-> $crate::strategy::BoxedStrategy<Self>
where
S: $crate::strategy::Strategy<Value = A> + 'static
{
$crate::strategy::Strategy::boxed($logic)
}
}
};
([$($bounds : tt)*] $typ: ty; $base: ident => $logic: expr) => {
lift1!([$($bounds)*] $typ, (); $base, _args => $logic);
};
([$($bounds : tt)*] $typ: ty; $mapper: expr) => {
lift1!(['static + $($bounds)*] $typ; base =>
$crate::strategy::Strategy::prop_map(base, $mapper));
};
([$($bounds : tt)*] $typ: ty) => {
lift1!(['static + $($bounds)*] $typ; base =>
$crate::strategy::Strategy::prop_map_into(base));
};
}