1#![no_std]
20use core::cmp::min;
21
22use rand::{Error, RngCore, SeedableRng};
23
24pub mod tinymt32;
25pub mod tinymt64;
26
27#[derive(Default)]
28pub struct TinyMT64Seed(pub [u8; 8]);
29
30impl From<u64> for TinyMT64Seed {
31 fn from(seed: u64) -> Self {
32 TinyMT64Seed(seed.to_le_bytes())
33 }
34}
35
36impl From<TinyMT64Seed> for u64 {
37 fn from(seed: TinyMT64Seed) -> Self {
38 u64::from_le_bytes(seed.0)
39 }
40}
41
42impl AsMut<[u8]> for TinyMT64Seed {
43 fn as_mut(&mut self) -> &mut [u8] {
44 &mut self.0
45 }
46}
47
48#[derive(PartialEq, Eq, Debug, Copy, Clone)]
50pub struct TinyMT64 {
51 status: [u64; 2],
52 mat1: u32,
53 mat2: u32,
54 tmat: u64,
55}
56
57impl TinyMT64 {
58 pub fn from_seed_u64(seed: u64) -> Self {
59 Self::from_seed(TinyMT64Seed::from(seed))
60 }
61}
62
63impl SeedableRng for TinyMT64 {
64 type Seed = TinyMT64Seed;
65
66 fn from_seed(seed: Self::Seed) -> Self {
67 let mut random = TinyMT64 { status: [0, 0], mat1: 0, mat2: 0, tmat: 0 };
68 tinymt64::tinymt64_init(&mut random, u64::from(seed));
69 random
70 }
71}
72
73impl RngCore for TinyMT64 {
74 fn next_u32(&mut self) -> u32 {
75 self.next_u64() as u32
76 }
77
78 fn next_u64(&mut self) -> u64 {
79 tinymt64::tinymt64_generate_uint64(self)
80 }
81
82 fn fill_bytes(&mut self, dest: &mut [u8]) {
83 let mut position = 0;
84 let mut remaining = dest.len();
85 while remaining > 0 {
86 let bytes = self.next_u64().to_le_bytes();
87 for b in bytes.iter().take(min(remaining, bytes.len())) {
88 dest[position] = *b;
89 position += 1;
90 remaining -= 1;
91 }
92 }
93 }
94
95 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
96 self.fill_bytes(dest);
97 Ok(())
98 }
99}
100
101#[derive(Default)]
102pub struct TinyMT32Seed(pub [u8; 4]);
103
104impl From<u32> for TinyMT32Seed {
105 fn from(seed: u32) -> Self {
106 TinyMT32Seed(seed.to_le_bytes())
107 }
108}
109
110impl From<TinyMT32Seed> for u32 {
111 fn from(seed: TinyMT32Seed) -> Self {
112 u32::from_le_bytes(seed.0)
113 }
114}
115
116impl AsMut<[u8]> for TinyMT32Seed {
117 fn as_mut(&mut self) -> &mut [u8] {
118 &mut self.0
119 }
120}
121
122#[derive(PartialEq, Eq, Debug, Copy, Clone)]
124pub struct TinyMT32 {
125 status: [u32; 4],
126 mat1: u32,
127 mat2: u32,
128 tmat: u32,
129}
130
131impl TinyMT32 {
132 pub fn from_seed_u32(seed: u32) -> Self {
133 Self::from_seed(TinyMT32Seed::from(seed))
134 }
135}
136
137impl SeedableRng for TinyMT32 {
138 type Seed = TinyMT32Seed;
139
140 fn from_seed(seed: Self::Seed) -> Self {
141 let mut random = TinyMT32 { status: [0, 0, 0, 0], mat1: 0, mat2: 0, tmat: 0 };
142 tinymt32::tinymt32_init(&mut random, u32::from(seed));
143 random
144 }
145}
146
147impl RngCore for TinyMT32 {
148 fn next_u32(&mut self) -> u32 {
149 tinymt32::tinymt32_generate_uint32(self)
150 }
151
152 fn next_u64(&mut self) -> u64 {
153 ((self.next_u32() as u64) << 32) | (self.next_u32() as u64)
154 }
155
156 fn fill_bytes(&mut self, dest: &mut [u8]) {
157 let mut position = 0;
158 let mut remaining = dest.len();
159 while remaining > 0 {
160 let bytes = self.next_u32().to_le_bytes();
161 for b in bytes.iter().take(min(remaining, bytes.len())) {
162 dest[position] = *b;
163 position += 1;
164 remaining -= 1;
165 }
166 }
167 }
168
169 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error> {
170 self.fill_bytes(dest);
171 Ok(())
172 }
173}