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 11 use rand_core::{impls, Error, RngCore}; 12 13 #[cfg(feature = "serde1")] 14 use 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(Debug, Clone, PartialEq, Eq)] 31 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] 32 pub struct StepRng { 33 v: u64, 34 a: u64, 35 } 36 37 impl StepRng { 38 /// Create a `StepRng`, yielding an arithmetic sequence starting with 39 /// `initial` and incremented by `increment` each time. new(initial: u64, increment: u64) -> Self40 pub fn new(initial: u64, increment: u64) -> Self { 41 StepRng { 42 v: initial, 43 a: increment, 44 } 45 } 46 } 47 48 impl RngCore for StepRng { 49 #[inline] next_u32(&mut self) -> u3250 fn next_u32(&mut self) -> u32 { 51 self.next_u64() as u32 52 } 53 54 #[inline] next_u64(&mut self) -> u6455 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] fill_bytes(&mut self, dest: &mut [u8])62 fn fill_bytes(&mut self, dest: &mut [u8]) { 63 impls::fill_bytes_via_next(self, dest); 64 } 65 66 #[inline] try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>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)] 74 mod tests { 75 #[test] 76 #[cfg(feature = "serde1")] test_serialization_step_rng()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 } 88