rand/rngs/
mock.rs

1// Copyright 2018 Developers of the Rand project.
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Mock random number generator
10
11use rand_core::{impls, Error, RngCore};
12
13#[cfg(feature = "serde1")]
14use serde::{Serialize, Deserialize};
15
16/// A simple implementation of `RngCore` for testing purposes.
17///
18/// This generates an arithmetic sequence (i.e. adds a constant each step)
19/// over a `u64` number, using wrapping arithmetic. If the increment is 0
20/// the generator yields a constant.
21///
22/// ```
23/// use rand::Rng;
24/// use rand::rngs::mock::StepRng;
25///
26/// let mut my_rng = StepRng::new(2, 1);
27/// let sample: [u64; 3] = my_rng.gen();
28/// assert_eq!(sample, [2, 3, 4]);
29/// ```
30#[derive(#[automatically_derived]
impl ::core::fmt::Debug for StepRng {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "StepRng", "v",
            &self.v, "a", &&self.a)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for StepRng {
    #[inline]
    fn clone(&self) -> StepRng {
        StepRng {
            v: ::core::clone::Clone::clone(&self.v),
            a: ::core::clone::Clone::clone(&self.a),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for StepRng {
    #[inline]
    fn eq(&self, other: &StepRng) -> bool {
        self.v == other.v && self.a == other.a
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for StepRng {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_receiver_is_total_eq(&self) -> () {
        let _: ::core::cmp::AssertParamIsEq<u64>;
    }
}Eq)]
31#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
32pub struct StepRng {
33    v: u64,
34    a: u64,
35}
36
37impl StepRng {
38    /// Create a `StepRng`, yielding an arithmetic sequence starting with
39    /// `initial` and incremented by `increment` each time.
40    pub fn new(initial: u64, increment: u64) -> Self {
41        StepRng {
42            v: initial,
43            a: increment,
44        }
45    }
46}
47
48impl RngCore for StepRng {
49    #[inline]
50    fn next_u32(&mut self) -> u32 {
51        self.next_u64() as u32
52    }
53
54    #[inline]
55    fn next_u64(&mut self) -> u64 {
56        let result = self.v;
57        self.v = self.v.wrapping_add(self.a);
58        result
59    }
60
61    #[inline]
62    fn fill_bytes(&mut self, dest: &mut [u8]) {
63        impls::fill_bytes_via_next(self, dest);
64    }
65
66    #[inline]
67    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
68        self.fill_bytes(dest);
69        Ok(())
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    #[test]
76    #[cfg(feature = "serde1")]
77    fn test_serialization_step_rng() {
78        use super::StepRng;
79
80        let some_rng = StepRng::new(42, 7);
81        let de_some_rng: StepRng =
82            bincode::deserialize(&bincode::serialize(&some_rng).unwrap()).unwrap();
83        assert_eq!(some_rng.v, de_some_rng.v);
84        assert_eq!(some_rng.a, de_some_rng.a);
85
86    }
87}