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
93
94
95
use crate::{DieOnce, Limit, Prng};
/// Contains parameters for controlling the value generation with [`DieOnce`] and [`Die`].
///
/// The first parameter is a [`Prng`]. It is the only source of randomness that a implementor of
/// [`DieOnce`] or [`Die`] is allowed to use. Using the [`Prng`] will mutate its state, but for
/// the cause of preventing misuse there is no direct write access to it.
///
/// The second parameter is a [`Limit`]. It's the upper limit for the length of dynamic data
/// structures generated by the implementor of `DieOnce` or [`Die`]. The implementor has only read
/// access to the [`Limit`].
///
/// [`Die`]: crate::Die
pub struct Fate<'a> {
prng: &'a mut Prng,
limit: Limit,
}
impl<'a> Fate<'a> {
/// Creates a new instance that uses the given parameters for value generation.
pub fn new(prng: &'a mut Prng, limit: Limit) -> Self {
Self { prng, limit }
}
/// Returns the next pseudorandom number generated with the underlying [`Prng`].
pub fn next_number(&mut self) -> u64 {
self.prng.next_number()
}
/// Returns a [`Prng`] split off from the underlying [`Prng`].
pub fn fork_prng(&mut self) -> Prng {
self.prng.fork()
}
/// Returns the underlying [`Limit`].
pub fn limit(&self) -> Limit {
self.limit
}
/// Creates a borrowed copy.
///
/// [`Fate`] cannot implement the [`Copy`] trait because it contains a mutable
/// reference. When it's necessary to move [`Fate`] multiple times this functions provides a
/// convenient workaround.
///
/// # Example
///
/// ```
/// use dicetest::{Limit, Fate, Prng};
///
/// let mut prng = Prng::from_seed(42.into());
/// let limit = Limit::default();
/// let mut fate = Fate::new(&mut prng, limit);
///
/// pub fn take_fate(_fate: Fate) {}
///
/// take_fate(fate.copy());
/// take_fate(fate);
/// ```
pub fn copy<'b>(&'b mut self) -> Fate<'b> {
Fate {
prng: self.prng,
limit: self.limit,
}
}
/// Creates a copy with the given limit.
pub fn with_limit<'b>(&'b mut self, limit: Limit) -> Fate<'b> {
let mut fate = self.copy();
fate.limit = limit;
fate
}
/// Generates a value with the given [`DieOnce`] using `self` as parameter.
///
/// This function is more convenient than calling [`DieOnce::roll_once`] directly because
/// it borrows the [`Fate`] instead of moving it.
///
/// ```
/// use dicetest::prelude::*;
/// use dicetest::{Limit, Prng};
///
/// let mut prng = Prng::from_seed(42.into());
/// let limit = Limit::default();
/// let mut fate = Fate::new(&mut prng, limit);
///
/// let die = dice::bool();
///
/// let val1 = fate.roll(&die); // Borrows `fate`
/// let val2 = die.roll(fate); // Moves `fate`
/// ```
pub fn roll<T, D: DieOnce<T>>(&mut self, die: D) -> T {
die.roll_once(self.copy())
}
}