use self::private::PermuteKeyPrivate;
use crate::usize_generator::PermuteKeyData;
mod private {
use crate::usize_generator::{PermuteKeyData, UsizeGenerator};
pub trait PermuteKeyPrivate {
fn make_usize_random_generator(self, len: u64) -> UsizeGenerator;
}
impl<'a> PermuteKeyPrivate for &'a [u8] {
fn make_usize_random_generator(self, len: u64) -> UsizeGenerator {
let mut rand_builder = PermuteKeyData::new();
rand_builder.add_bytes(self);
rand_builder.make_usize_random_generator(len)
}
}
impl<'a> PermuteKeyPrivate for &'a mut [u8] {
fn make_usize_random_generator(self, len: u64) -> UsizeGenerator {
(&*self).make_usize_random_generator(len)
}
}
impl PermuteKeyPrivate for PermuteKeyData {
fn make_usize_random_generator(mut self, len: u64) -> UsizeGenerator {
self.add_bytes(&len.to_le_bytes());
self.into_usize_generator()
}
}
}
pub trait PermuteKey: PermuteKeyPrivate {}
impl<'a> PermuteKey for &'a [u8] {}
impl<'a> PermuteKey for &'a mut [u8] {}
impl PermuteKey for PermuteKeyData {}
pub fn permute<K: PermuteKey, T>(permute_key: K, data: &mut [T]) {
let mut rand = permute_key.make_usize_random_generator(data.len() as u64);
for (idx, max_swap_offset) in (1..data.len()).rev().enumerate() {
let swap_offset = rand.next_usize_max(max_swap_offset);
data.swap(idx, idx + swap_offset);
}
}