RandomKit
RandomKit copied to clipboard
revealing current seed as a public read-only property
Sometimes it might be helpful to be able to log seed that was used to create generator. So we can reproduce same random sequence using that seed we know.
For example it can be logged for test suit session whose data is generated randomly. And if some tests fail, we can fix them and re-run test suit using that seed to verify it on the same 'random' data.
Side note: this makes me wish Swift had more of Rust's abilities regarding protocols/traits.
How I'd implement Seedable
in Rust:
pub trait Seedable<S> {
fn from_seed(seed: S) -> Self where Self: Sized;
fn reseed(&mut self, seed: S);
}
Then there would be no need for SeedableFromSequence
since we would have a blanket implementation. This would require specialization, which Swift has out-of-the-box.
impl<S: IntoIterator<Item=u64>> Seedable<S> for ChaCha {
default fn from_seed(seed: S) -> ChaCha {
for s in seed.into_iter() {
/* ... */
}
}
default fn reseed(&mut self, seed: S) {
for s in seed.into_iter() {
/* ... */
}
}
}
impl<S> Seedable<S> for ChaCha
where
S: for<'a> IntoIterator<Item=&'a u64>
{
default fn from_seed(seed: S) -> ChaCha {
// Dereference the integer
let iter = seed.map(|&s| s);
ChaCha::from_seed(iter)
}
default fn reseed(&mut self, seed: S) {
// Dereference the integer
let iter = seed.map(|&s| s);
self.reseed(iter)
}
}
Specialization would allow for:
impl Seedable<u64> for ChaCha {
fn from_seed(seed: u64) -> ChaCha {
ChaCha::from_seed(&[seed])
}
fn reseed(&mut self, seed: u64) {
self.reseed(&[seed])
}
}
Edit: apparently because of problems with specialization, this implementation wouldn't be currently possible in Rust either 😢
https://play.rust-lang.org/?gist=409dba7bc6162833285c8437815bc178&version=nightly