permoot 0.2.1

General-purpose no_std permutation library
Documentation
use core::cmp::Ordering;

pub struct CycleIter<'a> {
	data: &'a [usize],
	index: usize,
}

impl<'a> Iterator for CycleIter<'a> {
	type Item = (usize, usize);

	fn next(&mut self) -> Option<Self::Item> {
		let curr = *self.data.get(self.index)?;

		let next = self
			.data
			.get(self.index.wrapping_add(1))
			.copied()
			.unwrap_or_else(|| self.data[0]);

		self.index += 1;

		Some((curr, next))
	}
}

pub fn cycle_iter(sl: &[usize]) -> CycleIter {
	CycleIter { data: sl, index: 0 }
}

pub fn copy_to_array<const N: usize>(sl: &[usize]) -> Option<[usize; N]> {
	let mut res = [0; N];
	(sl.len() == N).then(|| {
		res.copy_from_slice(sl);
		res
	})
}

pub fn range_array<const N: usize>() -> [usize; N] {
	let mut arr = [0; N];
	for (i, x) in arr.iter_mut().enumerate() {
		*x = i;
	}
	arr
}

#[cfg(test)]
pub fn with_random_perms<const N: usize>(n_seeds: usize, f: impl Fn(crate::Permutation<N>)) {
	use rand::{Rng, SeedableRng};
	use rand_chacha::ChaCha8Rng;

	let mut seed_rng = ChaCha8Rng::seed_from_u64(0xC418);

	let mut seeds = vec![0; n_seeds];
	seed_rng.fill(&mut seeds[..]);

	for seed in seeds {
		let mut rng = ChaCha8Rng::seed_from_u64(seed);

		let perm: crate::Permutation<N> = rng.gen();

		f(perm);
	}
}

#[derive(Copy, Clone)]
pub struct AlwaysEq<T>(pub T);

impl<T> Ord for AlwaysEq<T> {
	#[inline]
	fn cmp(&self, _other: &Self) -> Ordering {
		Ordering::Equal
	}
}

impl<T> PartialOrd for AlwaysEq<T> {
	#[inline]
	fn partial_cmp(&self, _other: &Self) -> Option<Ordering> {
		Some(Ordering::Equal)
	}
}

impl<T> PartialEq for AlwaysEq<T> {
	#[inline]
	fn eq(&self, _other: &Self) -> bool {
		true
	}
}

impl<T> Eq for AlwaysEq<T> {}