1//-
2// Copyright 2017, 2018 The proptest developers
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
910use crate::std_facade::fmt;
1112use crate::strategy::{NewTree, Strategy, ValueTree};
13use crate::test_runner::TestRunner;
1415macro_rules! noshrink {
16 () => {
17fn simplify(&mut self) -> bool {
18false
19}
20fn complicate(&mut self) -> bool {
21false
22}
23 };
24}
2526//==============================================================================
27// Just
28//==============================================================================
2930/// A `Strategy` which always produces a single value value and never
31/// simplifies.
32#[derive(Clone, Copy, Debug)]
33#[must_use = "strategies do nothing unless used"]
34pub struct Just<T: Clone + fmt::Debug>(
35/// The value produced by this strategy.
36pub T,
37);
3839impl<T: Clone + fmt::Debug> Strategy for Just<T> {
40type Tree = Self;
41type Value = T;
4243fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
44Ok(self.clone())
45 }
46}
4748impl<T: Clone + fmt::Debug> ValueTree for Just<T> {
49type Value = T;
50noshrink!();
51fn current(&self) -> T {
52self.0.clone()
53 }
54}
5556//==============================================================================
57// LazyJust
58//==============================================================================
5960/// A `Strategy` which always produces a single value value and never
61/// simplifies. If `T` is `Clone`, you should use `Just` instead.
62///
63/// This is a generalization of `Just` and works by calling
64/// the provided `Fn () -> T` in `.current()` every time. This is not a
65/// very interesting strategy, but is required in cases where `T` is
66/// not `Clone`. It is also used in `proptest_derive` where we can't
67/// assume that your type is `Clone`.
68///
69/// **It is important that the function used be pure.**
70#[must_use = "strategies do nothing unless used"]
71pub struct LazyJust<T, F: Fn() -> T> {
72/// The function executed in `.current()`.
73function: F,
74}
7576/// Shorthand for `LazyJust<T, fn () -> T>`.
77pub type LazyJustFn<V> = LazyJust<V, fn() -> V>;
7879impl<T, F: Fn() -> T> LazyJust<T, F> {
80/// Constructs a `LazyJust` strategy given the function/closure
81 /// that produces the value.
82 ///
83 /// **It is important that the function used be pure.**
84pub fn new(function: F) -> Self {
85Self { function }
86 }
87}
8889impl<T: fmt::Debug, F: Clone + Fn() -> T> Strategy for LazyJust<T, F> {
90type Tree = Self;
91type Value = T;
9293fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
94Ok(self.clone())
95 }
96}
9798impl<T: fmt::Debug, F: Fn() -> T> ValueTree for LazyJust<T, F> {
99type Value = T;
100noshrink!();
101fn current(&self) -> Self::Value {
102 (self.function)()
103 }
104}
105106impl<T, F: Copy + Fn() -> T> Copy for LazyJust<T, F> {}
107108impl<T, F: Clone + Fn() -> T> Clone for LazyJust<T, F> {
109fn clone(&self) -> Self {
110Self {
111 function: self.function.clone(),
112 }
113 }
114}
115116impl<T, F: Fn() -> T> fmt::Debug for LazyJust<T, F> {
117fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
118 fmt.debug_struct("LazyJust")
119 .field("function", &"<function>")
120 .finish()
121 }
122}
123124//==============================================================================
125// Any `fn () -> T` is a Strategy
126//==============================================================================
127128// TODO: try 'F: Fn () -> T' instead when we've got specialization.
129130impl<T: fmt::Debug> Strategy for fn() -> T {
131type Tree = Self;
132type Value = T;
133134fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
135Ok(*self)
136 }
137}
138139impl<T: fmt::Debug> ValueTree for fn() -> T {
140type Value = T;
141noshrink!();
142fn current(&self) -> Self::Value {
143self()
144 }
145}