| //- | 
 | // Copyright 2017 Jason Lingle | 
 | // | 
 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | 
 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | 
 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | 
 | // option. This file may not be copied, modified, or distributed | 
 | // except according to those terms. | 
 |  | 
 | //! Strategies for generating `bool` values. | 
 |  | 
 | use crate::strategy::*; | 
 | use crate::test_runner::*; | 
 |  | 
 | use rand::Rng; | 
 |  | 
 | /// The type of the `ANY` constant. | 
 | #[derive(Clone, Copy, Debug)] | 
 | pub struct Any(()); | 
 |  | 
 | /// Generates boolean values by picking `true` or `false` uniformly. | 
 | /// | 
 | /// Shrinks `true` to `false`. | 
 | pub const ANY: Any = Any(()); | 
 |  | 
 | impl Strategy for Any { | 
 |     type Tree = BoolValueTree; | 
 |     type Value = bool; | 
 |  | 
 |     fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> { | 
 |         Ok(BoolValueTree::new(runner.rng().gen())) | 
 |     } | 
 | } | 
 |  | 
 | /// Generates boolean values by picking `true` with the given `probability` | 
 | /// (1.0 = always true, 0.0 = always false). | 
 | /// | 
 | /// Shrinks `true` to `false`. | 
 | pub fn weighted(probability: f64) -> Weighted { | 
 |     Weighted(probability) | 
 | } | 
 |  | 
 | /// The return type from `weighted()`. | 
 | #[must_use = "strategies do nothing unless used"] | 
 | #[derive(Clone, Copy, Debug)] | 
 | pub struct Weighted(f64); | 
 |  | 
 | impl Strategy for Weighted { | 
 |     type Tree = BoolValueTree; | 
 |     type Value = bool; | 
 |  | 
 |     fn new_tree(&self, runner: &mut TestRunner) -> NewTree<Self> { | 
 |         Ok(BoolValueTree::new(runner.rng().gen_bool(self.0))) | 
 |     } | 
 | } | 
 |  | 
 | /// The `ValueTree` to shrink booleans to false. | 
 | #[derive(Clone, Copy, Debug)] | 
 | pub struct BoolValueTree { | 
 |     current: bool, | 
 |     state: ShrinkState, | 
 | } | 
 |  | 
 | #[derive(Clone, Copy, Debug, PartialEq)] | 
 | enum ShrinkState { | 
 |     Untouched, Simplified, Final | 
 | } | 
 |  | 
 | impl BoolValueTree { | 
 |     fn new(current: bool) -> Self { | 
 |         BoolValueTree { current, state: ShrinkState::Untouched } | 
 |     } | 
 | } | 
 |  | 
 | impl ValueTree for BoolValueTree { | 
 |     type Value = bool; | 
 |  | 
 |     fn current(&self) -> bool { self.current } | 
 |     fn simplify(&mut self) -> bool { | 
 |         match self.state { | 
 |             ShrinkState::Untouched if self.current => { | 
 |                 self.current = false; | 
 |                 self.state = ShrinkState::Simplified; | 
 |                 true | 
 |             }, | 
 |  | 
 |             ShrinkState::Untouched | ShrinkState::Simplified | | 
 |             ShrinkState::Final => { | 
 |                 self.state = ShrinkState::Final; | 
 |                 false | 
 |             }, | 
 |         } | 
 |     } | 
 |     fn complicate(&mut self) -> bool { | 
 |         match self.state { | 
 |             ShrinkState::Untouched | ShrinkState::Final => { | 
 |                 self.state = ShrinkState::Final; | 
 |                 false | 
 |             }, | 
 |  | 
 |             ShrinkState::Simplified => { | 
 |                 self.current = true; | 
 |                 self.state = ShrinkState::Final; | 
 |                 true | 
 |             } | 
 |         } | 
 |     } | 
 | } | 
 |  | 
 | #[cfg(test)] | 
 | mod test { | 
 |     use super::*; | 
 |  | 
 |     #[test] | 
 |     fn test_sanity() { | 
 |         check_strategy_sanity(ANY, None); | 
 |     } | 
 |  | 
 |     #[test] | 
 |     fn shrinks_properly() { | 
 |         let mut tree = BoolValueTree::new(true); | 
 |         assert!(tree.simplify()); | 
 |         assert!(!tree.current()); | 
 |         assert!(!tree.clone().simplify()); | 
 |         assert!(tree.complicate()); | 
 |         assert!(!tree.clone().complicate()); | 
 |         assert!(tree.current()); | 
 |         assert!(!tree.simplify()); | 
 |         assert!(tree.current()); | 
 |  | 
 |         tree = BoolValueTree::new(false); | 
 |         assert!(!tree.clone().simplify()); | 
 |         assert!(!tree.clone().complicate()); | 
 |         assert!(!tree.current()); | 
 |     } | 
 | } |