summaryrefslogtreecommitdiff
path: root/src/random.rs
blob: 334b6bf6b6656852ca3ed23f7b0876d45f1c6a47 (plain)
use rand::{Rng, SeedableRng, TryRng, rngs::SmallRng};

mod tortuise {
	#[link(wasm_import_module = "tortuise")]
	unsafe extern "C" {
		pub safe fn random_u64() -> u64;
	}
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TortuiseRng(SmallRng);

impl TortuiseRng {
	pub fn new() -> Self {
		Self::seed_from_u64(tortuise::random_u64())
	}
}

impl Default for TortuiseRng {
	fn default() -> Self {
		Self::new()
	}
}

impl SeedableRng for TortuiseRng {
	type Seed = <SmallRng as SeedableRng>::Seed;

	fn from_seed(seed: Self::Seed) -> Self {
		Self(SmallRng::from_seed(seed))
	}

	fn seed_from_u64(state: u64) -> Self {
		Self(SmallRng::seed_from_u64(state))
	}

	fn from_rng<R: Rng + ?Sized>(rng: &mut R) -> Self {
		Self(SmallRng::from_rng(rng))
	}

	fn try_from_rng<R: TryRng + ?Sized>(rng: &mut R) -> Result<Self, R::Error> {
		Ok(Self(SmallRng::try_from_rng(rng)?))
	}

	fn fork(&mut self) -> Self
	where
		Self: Rng,
	{
		Self(self.0.fork())
	}

	fn try_fork(&mut self) -> Result<Self, <Self as TryRng>::Error>
	where
		Self: TryRng,
	{
		Ok(Self(self.0.try_fork()?))
	}
}

impl TryRng for TortuiseRng {
	type Error = <SmallRng as TryRng>::Error;

	fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
		self.0.try_next_u32()
	}

	fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
		self.0.try_next_u64()
	}

	fn try_fill_bytes(&mut self, dst: &mut [u8]) -> Result<(), Self::Error> {
		self.0.try_fill_bytes(dst)
	}
}