proptest/strategy/just.rs
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.
9
10use crate::std_facade::fmt;
11
12use crate::strategy::{NewTree, Strategy, ValueTree};
13use crate::test_runner::TestRunner;
14
15macro_rules! noshrink {
16 () => {
17 fn simplify(&mut self) -> bool {
18 false
19 }
20 fn complicate(&mut self) -> bool {
21 false
22 }
23 };
24}
25
26//==============================================================================
27// Just
28//==============================================================================
29
30/// 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.
36 pub T,
37);
38
39impl<T: Clone + fmt::Debug> Strategy for Just<T> {
40 type Tree = Self;
41 type Value = T;
42
43 fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
44 Ok(self.clone())
45 }
46}
47
48impl<T: Clone + fmt::Debug> ValueTree for Just<T> {
49 type Value = T;
50 noshrink!();
51 fn current(&self) -> T {
52 self.0.clone()
53 }
54}
55
56//==============================================================================
57// LazyJust
58//==============================================================================
59
60/// 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()`.
73 function: F,
74}
75
76/// Shorthand for `LazyJust<T, fn () -> T>`.
77pub type LazyJustFn<V> = LazyJust<V, fn() -> V>;
78
79impl<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.**
84 pub fn new(function: F) -> Self {
85 Self { function }
86 }
87}
88
89impl<T: fmt::Debug, F: Clone + Fn() -> T> Strategy for LazyJust<T, F> {
90 type Tree = Self;
91 type Value = T;
92
93 fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
94 Ok(self.clone())
95 }
96}
97
98impl<T: fmt::Debug, F: Fn() -> T> ValueTree for LazyJust<T, F> {
99 type Value = T;
100 noshrink!();
101 fn current(&self) -> Self::Value {
102 (self.function)()
103 }
104}
105
106impl<T, F: Copy + Fn() -> T> Copy for LazyJust<T, F> {}
107
108impl<T, F: Clone + Fn() -> T> Clone for LazyJust<T, F> {
109 fn clone(&self) -> Self {
110 Self {
111 function: self.function.clone(),
112 }
113 }
114}
115
116impl<T, F: Fn() -> T> fmt::Debug for LazyJust<T, F> {
117 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
118 fmt.debug_struct("LazyJust")
119 .field("function", &"<function>")
120 .finish()
121 }
122}
123
124//==============================================================================
125// Any `fn () -> T` is a Strategy
126//==============================================================================
127
128// TODO: try 'F: Fn () -> T' instead when we've got specialization.
129
130impl<T: fmt::Debug> Strategy for fn() -> T {
131 type Tree = Self;
132 type Value = T;
133
134 fn new_tree(&self, _: &mut TestRunner) -> NewTree<Self> {
135 Ok(*self)
136 }
137}
138
139impl<T: fmt::Debug> ValueTree for fn() -> T {
140 type Value = T;
141 noshrink!();
142 fn current(&self) -> Self::Value {
143 self()
144 }
145}