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="serde")] 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="serde", derive(Serialize, Deserialize))]
25pub struct IsaacArray<T> {
26    #[cfg_attr(feature="serde",serde(with="isaac_array_serde"))]
27    #[cfg_attr(feature="serde", 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// Custom PartialEq implementation as it can't currently be derived from an array of size RAND_SIZE
69impl<T> ::core::cmp::PartialEq for IsaacArray<T> where T: PartialEq {
70    fn eq(&self, other: &IsaacArray<T>) -> bool {
71        &self.inner[..] == &other.inner[..]
72    }
73}
74
75// Custom Eq implementation as it can't currently be derived from an array of size RAND_SIZE
76impl<T> ::core::cmp::Eq for IsaacArray<T> where T: Eq {
77}
78
79
80#[cfg(feature="serde")]
81pub(super) mod isaac_array_serde {
82    const RAND_SIZE_LEN: usize = 8;
83    const RAND_SIZE: usize = 1 << RAND_SIZE_LEN;
84
85    use serde::{Deserialize, Deserializer, Serialize, Serializer};
86    use serde::de::{Visitor,SeqAccess};
87    use serde::de;
88
89    use core::fmt;
90
91    pub fn serialize<T, S>(arr: &[T;RAND_SIZE], ser: S) -> Result<S::Ok, S::Error>
92    where
93        T: Serialize,
94        S: Serializer
95    {
96        use serde::ser::SerializeTuple;
97
98        let mut seq = ser.serialize_tuple(RAND_SIZE)?;
99
100        for e in arr.iter() {
101            seq.serialize_element(&e)?;
102        }
103
104        seq.end()
105    }
106
107    #[inline]
108    pub fn deserialize<'de, T, D>(de: D) -> Result<[T;RAND_SIZE], D::Error>
109    where
110        T: Deserialize<'de>+Default+Copy,
111        D: Deserializer<'de>,
112    {
113        use core::marker::PhantomData;
114        struct ArrayVisitor<T> {
115            _pd: PhantomData<T>,
116        };
117        impl<'de,T> Visitor<'de> for ArrayVisitor<T>
118        where
119            T: Deserialize<'de>+Default+Copy
120        {
121            type Value = [T; RAND_SIZE];
122
123            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
124                formatter.write_str("Isaac state array")
125            }
126
127            #[inline]
128            fn visit_seq<A>(self, mut seq: A) -> Result<[T; RAND_SIZE], A::Error>
129            where
130                A: SeqAccess<'de>,
131            {
132                let mut out = [Default::default();RAND_SIZE];
133
134                for i in 0..RAND_SIZE {
135                    match seq.next_element()? {
136                        Some(val) => out[i] = val,
137                        None => return Err(de::Error::invalid_length(i, &self)),
138                    };
139                }
140
141                Ok(out)
142            }
143        }
144
145        de.deserialize_tuple(RAND_SIZE, ArrayVisitor{_pd: PhantomData})
146    }
147}