Skip to content

Commit 58fd61d

Browse files
committed
Add back serde to IsacRng and Isaac64Rng
1 parent 610e975 commit 58fd61d

File tree

4 files changed

+83
-81
lines changed

4 files changed

+83
-81
lines changed

src/prng/isaac.rs

+13-37
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::{fmt, slice};
1414
use core::num::Wrapping as w;
1515
use rand_core::{BlockRngCore, RngCore, SeedableRng, Error, le};
1616
use rand_core::impls::BlockRng;
17+
use prng::isaac_array::IsaacArray;
1718

1819
#[allow(non_camel_case_types)]
1920
type w32 = w<u32>;
@@ -86,6 +87,7 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
8687
///
8788
/// [`Hc128Rng`]: hc128/struct.Hc128Rng.html
8889
#[derive(Clone, Debug)]
90+
#[cfg_attr(feature="serde-1", derive(Serialize, Deserialize))]
8991
pub struct IsaacRng(BlockRng<IsaacCore>);
9092

9193
impl RngCore for IsaacRng {
@@ -145,14 +147,16 @@ impl IsaacRng {
145147
// `seed == 0` this method produces exactly the same state as the
146148
// reference implementation when used unseeded.
147149
core: IsaacCore::init(key, 1),
148-
results: IsaacArray([0; RAND_SIZE]),
150+
results: IsaacArray::default(),
149151
index: RAND_SIZE, // generate on first use
150152
})
151153
}
152154
}
153155

154156
#[derive(Clone)]
157+
#[cfg_attr(feature="serde-1", derive(Serialize, Deserialize))]
155158
pub struct IsaacCore {
159+
#[cfg_attr(feature="serde-1",serde(with="super::isaac_array::isaac_array_serde"))]
156160
mem: [w32; RAND_SIZE],
157161
a: w32,
158162
b: w32,
@@ -166,37 +170,9 @@ impl fmt::Debug for IsaacCore {
166170
}
167171
}
168172

169-
// Terrible workaround because arrays with more than 32 elements do not
170-
// implement `AsRef` (or any other traits for that matter)
171-
#[derive(Copy, Clone)]
172-
#[allow(missing_debug_implementations)]
173-
pub struct IsaacArray([u32; RAND_SIZE]);
174-
impl ::core::convert::AsRef<[u32]> for IsaacArray {
175-
#[inline(always)]
176-
fn as_ref(&self) -> &[u32] {
177-
&self.0[..]
178-
}
179-
}
180-
impl ::core::ops::Deref for IsaacArray {
181-
type Target = [u32; RAND_SIZE];
182-
#[inline(always)]
183-
fn deref(&self) -> &Self::Target {
184-
&self.0
185-
}
186-
}
187-
impl ::core::ops::DerefMut for IsaacArray {
188-
#[inline(always)]
189-
fn deref_mut(&mut self) -> &mut [u32; RAND_SIZE] {
190-
&mut self.0
191-
}
192-
}
193-
impl ::core::default::Default for IsaacArray {
194-
fn default() -> IsaacArray { IsaacArray([0u32; RAND_SIZE]) }
195-
}
196-
197173
impl BlockRngCore for IsaacCore {
198174
type Item = u32;
199-
type Results = IsaacArray;
175+
type Results = IsaacArray<Self::Item>;
200176

201177
/// Refills the output buffer (`results`)
202178
/// See also the pseudocode desciption of the algorithm at the top of this
@@ -217,7 +193,7 @@ impl BlockRngCore for IsaacCore {
217193
/// from `results` in reverse. We read them in the normal direction, to
218194
/// make `fill_bytes` a memcopy. To maintain compatibility we fill in
219195
/// reverse.
220-
fn generate(&mut self, results: &mut IsaacArray) {
196+
fn generate(&mut self, results: &mut IsaacArray<Self::Item>) {
221197
self.c += w(1);
222198
// abbreviations
223199
let mut a = self.a;
@@ -493,17 +469,17 @@ mod test {
493469
let mut read = BufReader::new(&buf[..]);
494470
let mut deserialized: IsaacRng = bincode::deserialize_from(&mut read).expect("Could not deserialize");
495471

496-
assert_eq!(rng.index, deserialized.index);
472+
assert_eq!(rng.0.index, deserialized.0.index);
497473
/* Can't assert directly because of the array size */
498-
for (orig,deser) in rng.rsl.iter().zip(deserialized.rsl.iter()) {
474+
for (orig,deser) in rng.0.results.iter().zip(deserialized.0.results.iter()) {
499475
assert_eq!(orig, deser);
500476
}
501-
for (orig,deser) in rng.mem.iter().zip(deserialized.mem.iter()) {
477+
for (orig,deser) in rng.0.core.mem.iter().zip(deserialized.0.core.mem.iter()) {
502478
assert_eq!(orig, deser);
503479
}
504-
assert_eq!(rng.a, deserialized.a);
505-
assert_eq!(rng.b, deserialized.b);
506-
assert_eq!(rng.c, deserialized.c);
480+
assert_eq!(rng.0.core.a, deserialized.0.core.a);
481+
assert_eq!(rng.0.core.b, deserialized.0.core.b);
482+
assert_eq!(rng.0.core.c, deserialized.0.core.c);
507483

508484
for _ in 0..16 {
509485
assert_eq!(rng.next_u64(), deserialized.next_u64());

src/prng/isaac64.rs

+14-38
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use core::{fmt, slice};
1414
use core::num::Wrapping as w;
1515
use rand_core::{BlockRngCore, RngCore, SeedableRng, Error, le};
1616
use rand_core::impls::BlockRng64;
17+
use prng::isaac_array::IsaacArray;
1718

1819
#[allow(non_camel_case_types)]
1920
type w64 = w<u64>;
@@ -76,6 +77,7 @@ const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
7677
/// [`IsaacRng`]: ../isaac/struct.IsaacRng.html
7778
/// [`Hc128Rng`]: hc128/struct.Hc128Rng.html
7879
#[derive(Clone, Debug)]
80+
#[cfg_attr(feature="serde-1", derive(Serialize, Deserialize))]
7981
pub struct Isaac64Rng(BlockRng64<Isaac64Core>);
8082

8183
impl RngCore for Isaac64Rng {
@@ -134,15 +136,17 @@ impl Isaac64Rng {
134136
// `seed == 0` this method produces exactly the same state as the
135137
// reference implementation when used unseeded.
136138
core: Isaac64Core::init(key, 1),
137-
results: Isaac64Array([0; RAND_SIZE]),
139+
results: IsaacArray::default(),
138140
index: RAND_SIZE, // generate on first use
139141
half_used: false,
140142
})
141143
}
142144
}
143145

144146
#[derive(Clone)]
147+
#[cfg_attr(feature="serde-1", derive(Serialize, Deserialize))]
145148
pub struct Isaac64Core {
149+
#[cfg_attr(feature="serde-1",serde(with="super::isaac_array::isaac_array_serde"))]
146150
mem: [w64; RAND_SIZE],
147151
a: w64,
148152
b: w64,
@@ -156,37 +160,9 @@ impl fmt::Debug for Isaac64Core {
156160
}
157161
}
158162

159-
// Terrible workaround because arrays with more than 32 elements do not
160-
// implement `AsRef` (or any other traits for that matter)
161-
#[derive(Copy, Clone)]
162-
#[allow(missing_debug_implementations)]
163-
pub struct Isaac64Array([u64; RAND_SIZE]);
164-
impl ::core::convert::AsRef<[u64]> for Isaac64Array {
165-
#[inline(always)]
166-
fn as_ref(&self) -> &[u64] {
167-
&self.0[..]
168-
}
169-
}
170-
impl ::core::ops::Deref for Isaac64Array {
171-
type Target = [u64; RAND_SIZE];
172-
#[inline(always)]
173-
fn deref(&self) -> &Self::Target {
174-
&self.0
175-
}
176-
}
177-
impl ::core::ops::DerefMut for Isaac64Array {
178-
#[inline(always)]
179-
fn deref_mut(&mut self) -> &mut [u64; RAND_SIZE] {
180-
&mut self.0
181-
}
182-
}
183-
impl ::core::default::Default for Isaac64Array {
184-
fn default() -> Isaac64Array { Isaac64Array([0u64; RAND_SIZE]) }
185-
}
186-
187163
impl BlockRngCore for Isaac64Core {
188164
type Item = u64;
189-
type Results = Isaac64Array;
165+
type Results = IsaacArray<Self::Item>;
190166

191167
/// Refills the output buffer (`results`)
192168
/// See also the pseudocode desciption of the algorithm at the top of this
@@ -207,7 +183,7 @@ impl BlockRngCore for Isaac64Core {
207183
/// from `results` in reverse. We read them in the normal direction, to
208184
/// make `fill_bytes` a memcopy. To maintain compatibility we fill in
209185
/// reverse.
210-
fn generate(&mut self, results: &mut Isaac64Array) {
186+
fn generate(&mut self, results: &mut IsaacArray<Self::Item>) {
211187
self.c += w(1);
212188
// abbreviations
213189
let mut a = self.a;
@@ -486,18 +462,18 @@ mod test {
486462
let mut read = BufReader::new(&buf[..]);
487463
let mut deserialized: Isaac64Rng = bincode::deserialize_from(&mut read).expect("Could not deserialize");
488464

489-
assert_eq!(rng.index, deserialized.index);
490-
assert_eq!(rng.half_used, deserialized.half_used);
465+
assert_eq!(rng.0.index, deserialized.0.index);
466+
assert_eq!(rng.0.half_used, deserialized.0.half_used);
491467
/* Can't assert directly because of the array size */
492-
for (orig,deser) in rng.rsl.iter().zip(deserialized.rsl.iter()) {
468+
for (orig,deser) in rng.0.results.iter().zip(deserialized.0.results.iter()) {
493469
assert_eq!(orig, deser);
494470
}
495-
for (orig,deser) in rng.mem.iter().zip(deserialized.mem.iter()) {
471+
for (orig,deser) in rng.0.core.mem.iter().zip(deserialized.0.core.mem.iter()) {
496472
assert_eq!(orig, deser);
497473
}
498-
assert_eq!(rng.a, deserialized.a);
499-
assert_eq!(rng.b, deserialized.b);
500-
assert_eq!(rng.c, deserialized.c);
474+
assert_eq!(rng.0.core.a, deserialized.0.core.a);
475+
assert_eq!(rng.0.core.b, deserialized.0.core.b);
476+
assert_eq!(rng.0.core.c, deserialized.0.core.c);
501477

502478
for _ in 0..16 {
503479
assert_eq!(rng.next_u64(), deserialized.next_u64());

src/prng/isaac_serde.rs renamed to src/prng/isaac_array.rs

+55-4
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,60 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
//! ISAAC serde helper functions.
11+
//! ISAAC helper functions for 256-element arrays.
1212
13-
pub(super) mod rand_size_serde {
13+
// Terrible workaround because arrays with more than 32 elements do not
14+
// implement `AsRef`, `Default`, `Serialize`, `Deserialize`, or any other
15+
// traits for that matter.
16+
17+
#[cfg(feature="serde-1")] use serde::{Serialize, Deserialize};
18+
19+
const RAND_SIZE_LEN: usize = 8;
20+
const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
21+
22+
23+
#[derive(Copy, Clone)]
24+
#[allow(missing_debug_implementations)]
25+
#[cfg_attr(feature="serde-1", derive(Serialize, Deserialize))]
26+
pub struct IsaacArray<T> where T: Default + Copy {
27+
#[cfg_attr(feature="serde-1",serde(with="isaac_array_serde"))]
28+
#[cfg_attr(feature="serde-1", serde(bound(
29+
serialize = "T: Serialize",
30+
deserialize = "T: Deserialize<'de>")))]
31+
inner: [T; RAND_SIZE]
32+
}
33+
34+
impl<T> ::core::convert::AsRef<[T]> for IsaacArray<T> where T: Default + Copy {
35+
#[inline(always)]
36+
fn as_ref(&self) -> &[T] {
37+
&self.inner[..]
38+
}
39+
}
40+
41+
impl<T> ::core::ops::Deref for IsaacArray<T> where T: Default + Copy {
42+
type Target = [T; RAND_SIZE];
43+
#[inline(always)]
44+
fn deref(&self) -> &Self::Target {
45+
&self.inner
46+
}
47+
}
48+
49+
impl<T> ::core::ops::DerefMut for IsaacArray<T> where T: Default + Copy {
50+
#[inline(always)]
51+
fn deref_mut(&mut self) -> &mut [T; RAND_SIZE] {
52+
&mut self.inner
53+
}
54+
}
55+
56+
impl<T> ::core::default::Default for IsaacArray<T> where T: Default + Copy {
57+
fn default() -> IsaacArray<T> {
58+
IsaacArray { inner: [T::default(); RAND_SIZE] }
59+
}
60+
}
61+
62+
63+
#[cfg(feature="serde-1")]
64+
pub(super) mod isaac_array_serde {
1465
const RAND_SIZE_LEN: usize = 8;
1566
const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
1667

@@ -20,10 +71,10 @@ pub(super) mod rand_size_serde {
2071

2172
use core::fmt;
2273

23-
pub fn serialize<T, S>(arr: &[T;RAND_SIZE], ser: S) -> Result<S::Ok, S::Error>
74+
pub fn serialize<T, S>(arr: &[T;RAND_SIZE], ser: S) -> Result<S::Ok, S::Error>
2475
where
2576
T: Serialize,
26-
S: Serializer
77+
S: Serializer
2778
{
2879
use serde::ser::SerializeTuple;
2980

src/prng/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ mod isaac;
4646
mod isaac64;
4747
mod xorshift;
4848

49-
#[cfg(feature="serde-1")]
50-
mod isaac_serde;
49+
mod isaac_array;
5150

5251
#[doc(inline)] pub use self::chacha::ChaChaRng;
5352
#[doc(inline)] pub use self::hc128::Hc128Rng;

0 commit comments

Comments
 (0)