1use std::marker::PhantomData;
2use std::fmt::Debug;
3
4use super::*;
5
6use proptest::strategy::{Strategy, Map, ValueFor};
7pub (crate) use proptest::strategy::statics::{
8 Map as SMap,
9 MapFn as SMapFn,
10 };
13
14pub (crate) fn any_with_map<'a, A, B, F>(args: A::Parameters, fun: F)
15 -> Map<StrategyType<'a, A>, F>
16where
17 A: Arbitrary<'a>,
18 B: Debug,
19 F: Fn(A) -> B,
20{
21 any_with::<A>(args).prop_map(fun)
22}
23
24pub (crate) fn any_with_sinto<'a, A, B>(args: A::Parameters)
25 -> FMapped<'a, A, B>
26where A: Arbitrary<'a>,
27 B: Debug + From<A>
28{
29 from_map_strategy(any_with::<A>(args))
30}
31
32pub (crate) fn any_sinto<'a, A, B>()
33 -> FMapped<'a, A, B>
34where A: Arbitrary<'a>,
35 B: Debug + From<A>
36{
37 from_map_strategy(any::<A>())
38}
39
40pub (crate) fn any_with_smap<'a, A, B>(args: A::Parameters, fun: fn(A) -> B)
41 -> SMapped<'a, A, B>
42where
43 A: Arbitrary<'a>,
44 B: Debug,
45{
46 static_map(any_with::<A>(args), fun)
47}
48
49pub (crate) fn default<D: Default>() -> D { D::default() }
50
51
52#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
84pub struct FromMapper<I, O>(PhantomData<(I, O)>);
85
86impl<I, O> Default for FromMapper<I, O> {
87 fn default() -> Self { FromMapper(PhantomData) }
88}
89
90impl<I, O> Clone for FromMapper<I, O> {
91 fn clone(&self) -> Self { default() }
92}
93
94impl<I, O: From<I> + Debug> SMapFn<I> for FromMapper<I, O> {
95 type Output = O;
96
97 fn apply(&self, val: I) -> Self::Output {
98 val.into()
99 }
100}
101
102pub(crate) type FromMapStrategy<S, O> = SMap<S, FromMapper<ValueFor<S>, O>>;
103
104pub (crate) fn from_map_strategy<S: Strategy, O>(strat: S)
105 -> FromMapStrategy<S, O> {
106 FromMapStrategy::new(strat, default())
107}
108
109pub type FMapped<'a, I, O> = FromMapStrategy<StrategyType<'a, I>, O>;
111
112#[derive(Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
117pub struct SFnMap<I, O>(fn(I) -> O);
118
119impl<I, O> Clone for SFnMap<I, O> {
120 fn clone(&self) -> Self { SFnMap(self.0) }
121}
122
123impl<I, O: Debug> SMapFn<I> for SFnMap<I, O> {
124 type Output = O;
125 fn apply(&self, x: I) -> Self::Output { self.0(x) }
126}
127
128pub(crate) type StaticMap<S, I, O> = SMap<S, SFnMap<I, O>>;
129
130pub(crate) type SFnPtrMap<S, O> = SMap<S, SFnMap<ValueFor<S>, O>>;
131
132pub(crate) fn static_map<S, O>(strat: S, fun: fn(ValueFor<S>) -> O)
133 -> StaticMap<S, ValueFor<S>, O>
134where
135 S: Strategy,
136 O: Debug
137{
138 StaticMap::new(strat, SFnMap(fun))
139}
140
141pub type SMapped<'a, I, O> = SMap<StrategyType<'a, I>, SFnMap<I, O>>;
143
144pub type Mapped<'a, I, O> = Map<StrategyType<'a, I>, fn(I) -> O>;