rand_isaac/
isaac_array.rs

1// Copyright 2018 Developers of the Rand project.
2// Copyright 2017-2018 The Rust Project Developers.
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9
10//! ISAAC helper functions for 256-element arrays.
11
12// Terrible workaround because arrays with more than 32 elements do not
13// implement `AsRef`, `Default`, `Serialize`, `Deserialize`, or any other
14// traits for that matter.
15
16#[cfg(feature="serde1")] use serde::{Serialize, Deserialize};
17
18const RAND_SIZE_LEN: usize = 8;
19const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
20
21
22#[derive(Copy, Clone)]
23#[allow(missing_debug_implementations)]
24#[cfg_attr(feature="serde1", derive(Serialize, Deserialize))]
25pub struct IsaacArray<T> {
26    #[cfg_attr(feature="serde1",serde(with="isaac_array_serde"))]
27    #[cfg_attr(feature="serde1", serde(bound(
28        serialize = "T: Serialize",
29        deserialize = "T: Deserialize<'de> + Copy + Default")))]
30    inner: [T; RAND_SIZE]
31}
32
33impl<T> ::core::convert::AsRef<[T]> for IsaacArray<T> {
34    #[inline(always)]
35    fn as_ref(&self) -> &[T] {
36        &self.inner[..]
37    }
38}
39
40impl<T> ::core::convert::AsMut<[T]> for IsaacArray<T> {
41    #[inline(always)]
42    fn as_mut(&mut self) -> &mut [T] {
43        &mut self.inner[..]
44    }
45}
46
47impl<T> ::core::ops::Deref for IsaacArray<T> {
48    type Target = [T; RAND_SIZE];
49    #[inline(always)]
50    fn deref(&self) -> &Self::Target {
51        &self.inner
52    }
53}
54
55impl<T> ::core::ops::DerefMut for IsaacArray<T> {
56    #[inline(always)]
57    fn deref_mut(&mut self) -> &mut [T; RAND_SIZE] {
58        &mut self.inner
59    }
60}
61
62impl<T> ::core::default::Default for IsaacArray<T> where T: Copy + Default {
63    fn default() -> IsaacArray<T> {
64        IsaacArray { inner: [T::default(); RAND_SIZE] }
65    }
66}
67
68
69#[cfg(feature="serde1")]
70pub(super) mod isaac_array_serde {
71    const RAND_SIZE_LEN: usize = 8;
72    const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
73
74    use serde::{Deserialize, Deserializer, Serialize, Serializer};
75    use serde::de::{Visitor,SeqAccess};
76    use serde::de;
77
78    use core::fmt;
79
80    pub fn serialize<T, S>(arr: &[T;RAND_SIZE], ser: S) -> Result<S::Ok, S::Error>
81    where
82        T: Serialize,
83        S: Serializer
84    {
85        use serde::ser::SerializeTuple;
86
87        let mut seq = ser.serialize_tuple(RAND_SIZE)?;
88
89        for e in arr.iter() {
90            seq.serialize_element(&e)?;
91        }
92
93        seq.end()
94    }
95
96    #[inline]
97    pub fn deserialize<'de, T, D>(de: D) -> Result<[T;RAND_SIZE], D::Error>
98    where
99        T: Deserialize<'de>+Default+Copy,
100        D: Deserializer<'de>,
101    {
102        use core::marker::PhantomData;
103        struct ArrayVisitor<T> {
104            _pd: PhantomData<T>,
105        };
106        impl<'de,T> Visitor<'de> for ArrayVisitor<T>
107        where
108            T: Deserialize<'de>+Default+Copy
109        {
110            type Value = [T; RAND_SIZE];
111
112            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
113                formatter.write_str("Isaac state array")
114            }
115
116            #[inline]
117            fn visit_seq<A>(self, mut seq: A) -> Result<[T; RAND_SIZE], A::Error>
118            where
119                A: SeqAccess<'de>,
120            {
121                let mut out = [Default::default();RAND_SIZE];
122
123                for i in 0..RAND_SIZE {
124                    match seq.next_element()? {
125                        Some(val) => out[i] = val,
126                        None => return Err(de::Error::invalid_length(i, &self)),
127                    };
128                }
129
130                Ok(out)
131            }
132        }
133
134        de.deserialize_tuple(RAND_SIZE, ArrayVisitor{_pd: PhantomData})
135    }
136}