1use crate::empty::Empty;
6
7pub trait Rng {
11 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A>;
19
20 fn gen_u64(&self) -> Option<u64> {
24 self.fill([0; 8]).map(u64::from_le_bytes)
25 }
26
27 fn gen_u128(&self) -> Option<u128> {
31 self.fill([0; 16]).map(u128::from_le_bytes)
32 }
33}
34
35impl<'a, T: Rng + ?Sized> Rng for &'a T {
36 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A> {
37 (**self).fill(arr)
38 }
39
40 fn gen_u64(&self) -> Option<u64> {
41 (**self).gen_u64()
42 }
43
44 fn gen_u128(&self) -> Option<u128> {
45 (**self).gen_u128()
46 }
47}
48
49impl<'a, T: Rng> Rng for Option<T> {
50 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A> {
51 self.as_ref().and_then(|id| id.fill(arr))
52 }
53
54 fn gen_u64(&self) -> Option<u64> {
55 self.as_ref().and_then(|id| id.gen_u64())
56 }
57
58 fn gen_u128(&self) -> Option<u128> {
59 self.as_ref().and_then(|id| id.gen_u128())
60 }
61}
62
63#[cfg(feature = "alloc")]
64impl<'a, T: Rng + ?Sized + 'a> Rng for alloc::boxed::Box<T> {
65 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A> {
66 (**self).fill(arr)
67 }
68
69 fn gen_u64(&self) -> Option<u64> {
70 (**self).gen_u64()
71 }
72
73 fn gen_u128(&self) -> Option<u128> {
74 (**self).gen_u128()
75 }
76}
77
78#[cfg(feature = "alloc")]
79impl<'a, T: Rng + ?Sized + 'a> Rng for alloc::sync::Arc<T> {
80 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A> {
81 (**self).fill(arr)
82 }
83
84 fn gen_u64(&self) -> Option<u64> {
85 (**self).gen_u64()
86 }
87
88 fn gen_u128(&self) -> Option<u128> {
89 (**self).gen_u128()
90 }
91}
92
93impl Rng for Empty {
94 fn fill<A: AsMut<[u8]>>(&self, _: A) -> Option<A> {
95 None
96 }
97}
98
99mod internal {
100 pub trait DispatchRng {
101 fn dispatch_gen(&self, arr: &mut [u8]) -> bool;
102 fn dispatch_gen_u64(&self) -> Option<u64>;
103 fn dispatch_gen_u128(&self) -> Option<u128>;
104 }
105
106 pub trait SealedRng {
107 fn erase_rng(&self) -> crate::internal::Erased<&dyn DispatchRng>;
108 }
109}
110
111pub trait ErasedRng: internal::SealedRng {}
117
118impl<T: Rng> ErasedRng for T {}
119
120impl<T: Rng> internal::SealedRng for T {
121 fn erase_rng(&self) -> crate::internal::Erased<&dyn internal::DispatchRng> {
122 crate::internal::Erased(self)
123 }
124}
125
126impl<T: Rng> internal::DispatchRng for T {
127 fn dispatch_gen(&self, arr: &mut [u8]) -> bool {
128 self.fill(arr).is_some()
129 }
130
131 fn dispatch_gen_u64(&self) -> Option<u64> {
132 self.gen_u64()
133 }
134
135 fn dispatch_gen_u128(&self) -> Option<u128> {
136 self.gen_u128()
137 }
138}
139
140impl<'a> Rng for dyn ErasedRng + 'a {
141 fn fill<A: AsMut<[u8]>>(&self, mut arr: A) -> Option<A> {
142 if self.erase_rng().0.dispatch_gen(arr.as_mut()) {
143 Some(arr)
144 } else {
145 None
146 }
147 }
148
149 fn gen_u64(&self) -> Option<u64> {
150 self.erase_rng().0.dispatch_gen_u64()
151 }
152
153 fn gen_u128(&self) -> Option<u128> {
154 self.erase_rng().0.dispatch_gen_u128()
155 }
156}
157
158impl<'a> Rng for dyn ErasedRng + Send + Sync + 'a {
159 fn fill<A: AsMut<[u8]>>(&self, arr: A) -> Option<A> {
160 (self as &(dyn ErasedRng + 'a)).fill(arr)
161 }
162
163 fn gen_u64(&self) -> Option<u64> {
164 (self as &(dyn ErasedRng + 'a)).gen_u64()
165 }
166
167 fn gen_u128(&self) -> Option<u128> {
168 (self as &(dyn ErasedRng + 'a)).gen_u128()
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 struct MyRng {
177 fill: u8,
178 }
179
180 impl Rng for MyRng {
181 fn fill<A: AsMut<[u8]>>(&self, mut arr: A) -> Option<A> {
182 for b in arr.as_mut() {
183 *b = self.fill;
184 }
185
186 Some(arr)
187 }
188 }
189
190 #[test]
191 fn gen() {
192 for (rng, expected_u64, expected_u128) in [
193 (MyRng { fill: 0 }, 0u64, 0u128),
194 (MyRng { fill: u8::MAX }, u64::MAX, u128::MAX),
195 ] {
196 assert_eq!(expected_u64, rng.gen_u64().unwrap());
197 assert_eq!(expected_u128, rng.gen_u128().unwrap());
198 }
199 }
200
201 #[test]
202 fn option_rng() {
203 for (rng, expected) in [(Some(MyRng { fill: 42 }), Some([42u8, 42])), (None, None)] {
204 assert_eq!(expected, rng.fill([0, 0]));
205 }
206 }
207
208 #[test]
209 fn erased_rng() {
210 let rng = MyRng { fill: 42 };
211
212 let rng = &rng as &dyn ErasedRng;
213
214 assert_eq!([42, 42], rng.fill([0, 0]).unwrap());
215 }
216}