use crate::std_facade::fmt;
use crate::strategy::{BoxedStrategy, Strategy};
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));
};
}