Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
pitdicker committed Apr 2, 2018
1 parent acc9c5f commit c48e4cc
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 6 deletions.
79 changes: 75 additions & 4 deletions rand_core/src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,9 @@ pub fn next_u64_via_fill<R: RngCore + ?Sized>(rng: &mut R) -> u64 {
/// [`RngCore`]: ../RngCore.t.html
/// [`SeedableRng`]: ../SeedableRng.t.html
#[derive(Clone)]
#[cfg_attr(feature="serde-1", derive(Serialize,Deserialize))]
#[cfg_attr(feature="serde-1", derive(Serialize))]
pub struct BlockRng<R: BlockRngCore + ?Sized> {
#[cfg_attr(feature="serde-1", serde(with="serde_asref"))]
pub results: R::Results,
pub index: usize,
pub core: R,
Expand All @@ -203,7 +204,7 @@ impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng<R> {
}

impl<R: BlockRngCore<Item=u32>> RngCore for BlockRng<R>
where <R as BlockRngCore>::Results: AsRef<[u32]>
where <R as BlockRngCore>::Results: AsRef<[u32]> + AsMut<[u32]> + Default
{
#[inline(always)]
fn next_u32(&mut self) -> u32 {
Expand Down Expand Up @@ -349,7 +350,7 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng<R> {
/// [`RngCore`]: ../RngCore.t.html
/// [`BlockRng`]: .BlockRng.s.html
#[derive(Clone)]
#[cfg_attr(feature="serde-1", derive(Serialize,Deserialize))]
//#[cfg_attr(feature="serde-1", derive(Serialize,Deserialize))]
pub struct BlockRng64<R: BlockRngCore + ?Sized> {
pub results: R::Results,
pub index: usize,
Expand All @@ -370,7 +371,7 @@ impl<R: BlockRngCore + fmt::Debug> fmt::Debug for BlockRng64<R> {
}

impl<R: BlockRngCore<Item=u64>> RngCore for BlockRng64<R>
where <R as BlockRngCore>::Results: AsRef<[u64]>
where <R as BlockRngCore>::Results: AsRef<[u64]> + AsMut<[u64]> + Default
{
#[inline(always)]
fn next_u32(&mut self) -> u32 {
Expand Down Expand Up @@ -501,4 +502,74 @@ impl<R: BlockRngCore + SeedableRng> SeedableRng for BlockRng64<R> {

impl<R: BlockRngCore + CryptoRng> CryptoRng for BlockRng<R> {}

#[cfg(feature="serde-1")]
mod serde_asref {
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde::de::{Visitor,SeqAccess};
use serde::de;

use core::fmt;
use core::convert::AsRef;
use BlockRngCore;

pub fn serialize<R, S, T>(arr: R, ser: S) -> Result<S::Ok, S::Error>
where
R: AsRef<[T]>,
S: Serializer,
T: Serialize,
{
use serde::ser::SerializeTuple;

let mut seq = ser.serialize_tuple(arr.as_ref().len())?;

for e in arr.as_ref().iter() {
seq.serialize_element(&e)?;
}

seq.end()
}

#[inline]
pub fn deserialize<'de, R, T, D>(de: D) -> Result<[T;RAND_SIZE], D::Error>
where
R: AsMut<[T]>,
T: Deserialize<'de> + Default,
D: Deserializer<'de>,
{
use core::marker::PhantomData;
struct ArrayVisitor<T> {
_pd: PhantomData<T>,
};
impl<'de,T> Visitor<'de> for ArrayVisitor<T>
where
T: Deserialize<'de>+Default+Copy
{
type Value = [T; RAND_SIZE];

fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Isaac state array")
}

#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<[T; RAND_SIZE], A::Error>
where
A: SeqAccess<'de>,
{
let mut out = [Default::default();RAND_SIZE];

for i in 0..RAND_SIZE {
match seq.next_element()? {
Some(val) => out[i] = val,
None => return Err(de::Error::invalid_length(i, &self)),
};
}

Ok(out)
}
}

de.deserialize_tuple(RAND_SIZE, ArrayVisitor{_pd: PhantomData})
}
}

// TODO: implement tests for the above
8 changes: 6 additions & 2 deletions rand_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ use core::default::Default;
use core::convert::AsMut;

#[cfg(all(feature="alloc", not(feature="std")))] use alloc::boxed::Box;
#[cfg(feature="serde-1")] use serde::{Serialize, Deserialize};

pub use error::{ErrorKind, Error};

Expand Down Expand Up @@ -231,11 +232,14 @@ pub trait RngCore {
/// [`fill_bytes`]: trait.RngCore.html#tymethod.fill_bytes
pub trait BlockRngCore {
/// Results element type, e.g. `u32`.
#[cfg(not(feature="serde-1"))]
type Item;

#[cfg(feature="serde-1")]
type Item: Serialize;

/// Results type. This is the 'block' an RNG implementing `BlockRngCore`
/// generates, which will usually be an array like `[u32; 16]`.
type Results: AsRef<[Self::Item]> + Default;
type Results: AsRef<[Self::Item]> + AsMut<[Self::Item]> + Default;

/// Generate a new block of results.
fn generate(&mut self, results: &mut Self::Results);
Expand Down

0 comments on commit c48e4cc

Please sign in to comment.