Skip to content

Commit 83386f0

Browse files
committed
Add Isaac 32 Serde
1 parent f8609d8 commit 83386f0

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

src/isaac.rs

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ use std::slice;
1616
use std::iter::repeat;
1717
use std::num::Wrapping as w;
1818
use std::fmt;
19+
#[cfg(feature = "serde-1")]
20+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
21+
#[cfg(feature="serde-1")]
22+
use serde::de::Visitor;
1923

2024
use {Rng, SeedableRng, Rand, w32, w64};
2125

@@ -267,6 +271,207 @@ impl fmt::Debug for IsaacRng {
267271
}
268272
}
269273

274+
#[cfg(feature = "serde-1")]
275+
impl Serialize for IsaacRng {
276+
fn serialize<S>(&self, ser: S) -> Result<S::Ok, S::Error>
277+
where
278+
S: Serializer,
279+
{
280+
use serde::ser::SerializeStruct;
281+
282+
fn unwrap_u32(wrapped: &[w32; RAND_SIZE_USIZE], buf: &mut [u32]) {
283+
debug_assert_eq!(buf.len(), wrapped.len());
284+
for (i,&w(val)) in wrapped.iter().enumerate() {
285+
buf[i] = val;
286+
}
287+
}
288+
289+
let mut buf = vec![0;RAND_SIZE_USIZE];
290+
291+
let mut state = ser.serialize_struct("IsaacRng",6)?;
292+
293+
state.serialize_field("cnt", &self.cnt)?;
294+
295+
/* Unlike ChaCha, we need vecs here because the auto-derives don't go up
296+
to 256-element arrays */
297+
298+
unwrap_u32(&self.rsl, &mut buf);
299+
state.serialize_field("rsl", &buf)?;
300+
301+
unwrap_u32(&self.mem, &mut buf);
302+
state.serialize_field("mem", &buf)?;
303+
304+
let w(a) = self.a;
305+
state.serialize_field("a", &a)?;
306+
307+
let w(b) = self.b;
308+
state.serialize_field("b", &b)?;
309+
310+
let w(c) = self.c;
311+
state.serialize_field("c", &c)?;
312+
313+
state.end()
314+
}
315+
}
316+
317+
#[cfg(feature="serde-1")]
318+
impl<'de> Deserialize<'de> for IsaacRng {
319+
fn deserialize<D>(de: D) -> Result<IsaacRng, D::Error>
320+
where D: Deserializer<'de> {
321+
use serde::de::{SeqAccess,MapAccess};
322+
use serde::de;
323+
324+
enum Field { Cnt, Rsl, Mem, A, B, C };
325+
326+
impl<'de> Deserialize<'de> for Field {
327+
fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
328+
where D: Deserializer<'de> {
329+
struct IsaacFieldVisitor;
330+
impl<'de> Visitor<'de> for IsaacFieldVisitor {
331+
type Value = Field;
332+
333+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
334+
formatter.write_str("`cnt`, `rsl`, `mem`, `a`, `b`, or `c`")
335+
}
336+
337+
fn visit_str<E>(self, value: &str) -> Result<Field,E>
338+
where E: de::Error {
339+
match value {
340+
"cnt" => Ok(Field::Cnt),
341+
"rsl" => Ok(Field::Rsl),
342+
"mem" => Ok(Field::Mem),
343+
"a" => Ok(Field::A),
344+
"b" => Ok(Field::B),
345+
"c" => Ok(Field::C),
346+
_ => Err(de::Error::unknown_field(value, FIELDS))
347+
}
348+
}
349+
}
350+
deserializer.deserialize_identifier(IsaacFieldVisitor)
351+
}
352+
}
353+
354+
struct IsaacVisitor;
355+
356+
fn wrap_u32(unwrapped: &[u32]) -> [w32;RAND_SIZE_USIZE] {
357+
let mut buf = [w(0); RAND_SIZE_USIZE];
358+
for (i,&val) in unwrapped.into_iter().enumerate() {
359+
buf[i] = w(val);
360+
}
361+
buf
362+
}
363+
364+
const FIELDS: &[&'static str] = &["cnt","rsl", "mem","a", "b", "c"];
365+
366+
impl<'de> Visitor<'de> for IsaacVisitor {
367+
type Value = IsaacRng;
368+
369+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
370+
formatter.write_str("struct IsaacRng")
371+
}
372+
373+
fn visit_seq<V>(self, mut seq: V) -> Result<IsaacRng, V::Error>
374+
where V: SeqAccess<'de> {
375+
let cnt: u32 = seq.next_element()?
376+
.ok_or_else(|| de::Error::invalid_length(0,&self))?;
377+
378+
let rsl: Vec<u32> = seq.next_element()?
379+
.ok_or_else(|| de::Error::invalid_length(1, &self))?;
380+
381+
let mem: Vec<u32> = seq.next_element()?
382+
.ok_or_else(|| de::Error::invalid_length(2, &self))?;
383+
384+
let a: u32 = seq.next_element()?
385+
.ok_or_else(|| de::Error::invalid_length(3, &self))?;
386+
387+
let b: u32 = seq.next_element()?
388+
.ok_or_else(|| de::Error::invalid_length(4, &self))?;
389+
390+
let c: u32 = seq.next_element()?
391+
.ok_or_else(|| de::Error::invalid_length(5, &self))?;
392+
393+
let rsl = wrap_u32(&rsl);
394+
let mem = wrap_u32(&mem);
395+
396+
let (a,b,c) = (w(a), w(b), w(c));
397+
398+
Ok(IsaacRng {
399+
cnt, rsl, mem, a, b, c,
400+
})
401+
}
402+
403+
fn visit_map<V>(self, mut map: V) -> Result<IsaacRng, V::Error>
404+
where V: MapAccess<'de>
405+
{
406+
let mut cnt = None;
407+
let mut rsl: Option<Vec<u32>> = None;
408+
let mut mem: Option<Vec<u32>> = None;
409+
let mut a = None;
410+
let mut b = None;
411+
let mut c = None;
412+
413+
while let Some(key) = map.next_key()? {
414+
match key {
415+
Field::Cnt => {
416+
if cnt.is_some() {
417+
return Err(de::Error::duplicate_field("cnt"));
418+
}
419+
cnt = Some(map.next_value()?);
420+
}
421+
Field::Rsl => {
422+
if rsl.is_some() {
423+
return Err(de::Error::duplicate_field("rsl"));
424+
}
425+
rsl = Some(map.next_value()?);
426+
}
427+
Field::Mem => {
428+
if mem.is_some() {
429+
return Err(de::Error::duplicate_field("mem"));
430+
}
431+
mem = Some(map.next_value()?);
432+
}
433+
Field::A => {
434+
if a.is_some() {
435+
return Err(de::Error::duplicate_field("a"));
436+
}
437+
a = Some(map.next_value()?);
438+
}
439+
Field::B => {
440+
if b.is_some() {
441+
return Err(de::Error::duplicate_field("b"));
442+
}
443+
b = Some(map.next_value()?);
444+
}
445+
Field::C => {
446+
if c.is_some() {
447+
return Err(de::Error::duplicate_field("c"));
448+
}
449+
c = Some(map.next_value()?);
450+
}
451+
}
452+
}
453+
let cnt = cnt.ok_or_else(|| de::Error::missing_field("cnt"))?;
454+
let rsl = rsl.ok_or_else(|| de::Error::missing_field("rsl"))?;
455+
let mem = mem.ok_or_else(|| de::Error::missing_field("mem"))?;
456+
let a = a.ok_or_else(|| de::Error::missing_field("a"))?;
457+
let b = b.ok_or_else(|| de::Error::missing_field("b"))?;
458+
let c = c.ok_or_else(|| de::Error::missing_field("c"))?;
459+
460+
let rsl = wrap_u32(&rsl);
461+
let mem = wrap_u32(&mem);
462+
463+
let (a,b,c) = (w(a),w(b),w(c));
464+
465+
Ok(IsaacRng {
466+
cnt, rsl, mem, a, b, c,
467+
})
468+
}
469+
}
470+
471+
de.deserialize_struct("IsaacRng", FIELDS, IsaacVisitor)
472+
}
473+
}
474+
270475
const RAND_SIZE_64_LEN: usize = 8;
271476
const RAND_SIZE_64: usize = 1 << RAND_SIZE_64_LEN;
272477

@@ -632,4 +837,38 @@ mod test {
632837
assert_eq!(rng.next_u64(), clone.next_u64());
633838
}
634839
}
840+
841+
#[test]
842+
#[cfg(feature="serde-1")]
843+
fn test_rng_32_serde() {
844+
use bincode;
845+
use std::io::{BufWriter, BufReader};
846+
847+
let seed: &[_] = &[1, 23, 456, 7890, 12345];
848+
let mut rng: IsaacRng = SeedableRng::from_seed(seed);
849+
850+
let buf: Vec<u8> = Vec::new();
851+
let mut buf = BufWriter::new(buf);
852+
bincode::serialize_into(&mut buf, &rng, bincode::Infinite).expect("Could not serialize");
853+
854+
let buf = buf.into_inner().unwrap();
855+
let mut read = BufReader::new(&buf[..]);
856+
let mut deserialized: IsaacRng = bincode::deserialize_from(&mut read, bincode::Infinite).expect("Could not deserialize");
857+
858+
assert_eq!(rng.cnt, deserialized.cnt);
859+
/* Can't assert directly because of the array size */
860+
for (orig,deser) in rng.rsl.iter().zip(deserialized.rsl.iter()) {
861+
assert_eq!(orig, deser);
862+
}
863+
for (orig,deser) in rng.mem.iter().zip(deserialized.mem.iter()) {
864+
assert_eq!(orig, deser);
865+
}
866+
assert_eq!(rng.a, deserialized.a);
867+
assert_eq!(rng.b, deserialized.b);
868+
assert_eq!(rng.c, deserialized.c);
869+
870+
for _ in 0..16 {
871+
assert_eq!(rng.next_u64(), deserialized.next_u64());
872+
}
873+
}
635874
}

0 commit comments

Comments
 (0)