1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
use crate::die::adapters::{ArcDie, BoxedDie, FlatMapDie, FlattenDie, MapDie, RcDie}; use crate::die::{DieOnce, Fate, Limit}; use crate::prand::{Prng, Seed}; /// Trait for generating preudorandom values of type `T`. /// /// The `Die` trait represents a subset of `DieOnce`. It mirrors all methods of `DieOnce` without /// the suffix `_once`. These methods must behave in the same way. For example an implementation /// of `Die` must produce the same value with its methods `roll` and `roll_once` if they are called /// with the same `Fate`. pub trait Die<T>: DieOnce<T> { /// Generates a preudorandom value. /// /// The `Fate` is the only source of the randomness. Besides that, the generation is /// derterministic. fn roll(&self, fate: &mut Fate) -> T; /// Creates a new `Die` by mapping the generated values of `self`. /// /// The function `f` will be applied to the generated values of `self`. These function results /// are the generated values of the new `Die`. fn map<U, F>(self, f: F) -> MapDie<T, U, Self, F> where Self: Sized, F: Fn(T) -> U, { MapDie::new(self, f) } /// Creates a new `Die` whose values are generated by the generated `Die`s of `self`. fn flatten<U>(self) -> FlattenDie<U, T, Self> where Self: Sized, T: DieOnce<U>, { FlattenDie::new(self) } /// Creates a new `Die` similiar to `Die::map`, except that the mapping produces `DieOnce`s. /// /// The function `f` will be applied to the generated values of `self`. These function results /// are `DieOnce`s that generates the values for the new `Die`. /// /// It is semanticly equivalent to `self.map(f).flatten()`. fn flat_map<U, UD, F>(self, f: F) -> FlatMapDie<T, U, Self, UD, F> where Self: Sized, UD: DieOnce<U>, F: Fn(T) -> UD, { FlatMapDie::new(self, f) } /// Puts `self` behind a `Box` pointer. fn boxed<'a>(self) -> BoxedDie<'a, T> where Self: Sized + 'a, { BoxedDie::new(self) } /// Puts `self` behind an `Rc` pointer. fn rc<'a>(self) -> RcDie<'a, T> where Self: Sized + 'a, { RcDie::new(self) } /// Puts `self` behind an `Arc` pointer. fn arc(self) -> ArcDie<T> where Self: Sized + 'static, { ArcDie::new(self) } /// Calls `roll` with random `Seed` and default `Limit`. Useful for debugging the /// generator. fn sample(&self) -> T { self.sample_with_limit(Limit::default()) } /// Calls `roll` with random `Seed` and the given `Limit`. Useful for debugging the /// generator. fn sample_with_limit(&self, limit: Limit) -> T { let mut prng = Prng::from_seed(Seed::random()); let mut fate = Fate::new(&mut prng, limit); self.roll(&mut fate) } }