vitaminc_random/
generatable.rs1use crate::{RandomError, SafeRand};
17use std::num::NonZeroU16;
18use vitaminc_protected::{Controlled, Equatable, Exportable, Protected, Usage};
19
20pub trait Generatable: Sized {
24 fn random(rng: &mut SafeRand) -> Result<Self, RandomError>;
25}
26
27impl Generatable for NonZeroU16 {
28 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
29 let mut buf: [u8; 2] = [0, 0];
30 use rand::RngExt;
31 rng.fill(&mut buf);
32 if let Some(value) = NonZeroU16::new(u16::from_be_bytes(buf)) {
33 Ok(value)
34 } else {
35 Self::random(rng)
37 }
38 }
39}
40
41macro_rules! impl_generatable_for_int {
42 ($($t:ty),*) => {
43 $(
44 impl Generatable for $t {
45 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
46 use rand::RngExt;
47 Ok(rng.random())
48 }
49 }
50 )*
51 };
52}
53
54impl_generatable_for_int!(u8, u16, u32, u64, u128, i8, i16, i32, i64, i128);
55
56impl<const N: usize> Generatable for [u8; N] {
57 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
58 let mut buf: [u8; N] = [0; N];
60 use rand::RngExt;
61 rng.fill(&mut buf);
62 Ok(buf)
63 }
64}
65
66impl<T, G> Generatable for Protected<T>
67where
68 G: Generatable,
69 Self: Controlled<Inner = G>,
70{
71 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
72 Self::generate_ok(|| Generatable::random(rng))
73 }
74}
75
76impl<T, G> Generatable for Exportable<T>
77where
78 G: Generatable,
79 Self: Controlled<Inner = G>,
80{
81 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
82 Self::generate_ok(|| Generatable::random(rng))
83 }
84}
85
86impl<T, G> Generatable for Equatable<T>
87where
88 G: Generatable,
89 Self: Controlled<Inner = G>,
90{
91 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
92 Self::generate_ok(|| Generatable::random(rng))
93 }
94}
95
96impl<T, S, G> Generatable for Usage<T, S>
97where
98 G: Generatable,
99 Self: Controlled<Inner = G>,
100{
101 fn random(rng: &mut SafeRand) -> Result<Self, RandomError> {
102 Self::generate_ok(|| Generatable::random(rng))
103 }
104}
105
106#[cfg(test)]
107mod tests {
108 use super::Generatable;
109 use crate::SafeRand;
110 use zeroize::Zeroize;
111
112 fn assert_generatable<T>(rng: &mut SafeRand) -> T
113 where
114 T: super::Generatable,
115 {
116 T::random(rng).unwrap()
117 }
118
119 fn test_generate_controlled<T: Generatable + Zeroize>(rng: &mut SafeRand) {
120 use super::*;
121 let _: Protected<T> = assert_generatable(rng);
122 let _: Exportable<Protected<T>> = assert_generatable(rng);
123 let _: Equatable<Protected<T>> = assert_generatable(rng);
124 let _: Exportable<Equatable<Protected<T>>> = assert_generatable(rng);
125 let _: Usage<Protected<T>> = assert_generatable(rng);
126 let _: Usage<Equatable<Protected<T>>> = assert_generatable(rng);
127 }
128
129 #[test]
130 fn test_generate_array() -> Result<(), crate::RandomError> {
131 let mut rng = SafeRand::from_entropy()?;
132 let _: [u8; 4] = assert_generatable(&mut rng);
133 let _: [u8; 8] = assert_generatable(&mut rng);
134 let _: [u8; 16] = assert_generatable(&mut rng);
135 let _: [u8; 32] = assert_generatable(&mut rng);
136 let _: [u8; 64] = assert_generatable(&mut rng);
137 let _: [u8; 128] = assert_generatable(&mut rng);
138 let _: [u8; 256] = assert_generatable(&mut rng);
139 test_generate_controlled::<[u8; 4]>(&mut rng);
140 test_generate_controlled::<[u8; 8]>(&mut rng);
141 test_generate_controlled::<[u8; 16]>(&mut rng);
142 test_generate_controlled::<[u8; 32]>(&mut rng);
143 test_generate_controlled::<[u8; 64]>(&mut rng);
144 test_generate_controlled::<[u8; 128]>(&mut rng);
145 test_generate_controlled::<[u8; 256]>(&mut rng);
146 Ok(())
147 }
148
149 #[test]
150 fn test_numeric_primitives() -> Result<(), crate::RandomError> {
151 let mut rng = SafeRand::from_entropy()?;
152 let _: u8 = assert_generatable(&mut rng);
153 let _: u16 = assert_generatable(&mut rng);
154 let _: u32 = assert_generatable(&mut rng);
155 let _: u64 = assert_generatable(&mut rng);
156 let _: u128 = assert_generatable(&mut rng);
157 let _: i8 = assert_generatable(&mut rng);
158 let _: i16 = assert_generatable(&mut rng);
159 let _: i32 = assert_generatable(&mut rng);
160 let _: i64 = assert_generatable(&mut rng);
161 let _: i128 = assert_generatable(&mut rng);
162 test_generate_controlled::<u8>(&mut rng);
163 test_generate_controlled::<u16>(&mut rng);
164 test_generate_controlled::<u32>(&mut rng);
165 test_generate_controlled::<u64>(&mut rng);
166 test_generate_controlled::<u128>(&mut rng);
167 test_generate_controlled::<i8>(&mut rng);
168 test_generate_controlled::<i16>(&mut rng);
169 test_generate_controlled::<i32>(&mut rng);
170 test_generate_controlled::<i64>(&mut rng);
171 test_generate_controlled::<i128>(&mut rng);
172 Ok(())
173 }
174}