use core::ops::RangeBounds;
use osom_lib_reprc::{macros::reprc, traits::ReprC};
use crate::errors::{DeserializeError, SerializeError};
pub trait PRNConcreteGenerator<TGenerator: PRNGenerator>: Sized + ReprC {
#[must_use]
fn generate(generator: &mut TGenerator) -> Self;
}
pub trait PRNConcreteBoundedGenerator<TGenerator: PRNGenerator>: Sized + ReprC {
#[must_use]
fn generate<TBounds: RangeBounds<Self>>(generator: &mut TGenerator, range: TBounds) -> Self;
}
pub trait PRNGenerator: Sized + ReprC + Clone {
unsafe fn fill_raw(&mut self, dst_ptr: *mut u8, dst_len: usize);
#[inline(always)]
fn fill(&mut self, dst: &mut [u8]) {
unsafe {
self.fill_raw(dst.as_mut_ptr(), dst.len());
}
}
#[inline(always)]
#[must_use]
fn generate<T>(&mut self) -> T
where
T: PRNConcreteGenerator<Self>,
{
T::generate(self)
}
#[must_use]
fn generate_in_range<T, TBounds: RangeBounds<T>>(&mut self, range: TBounds) -> T
where
T: PRNConcreteBoundedGenerator<Self>,
{
T::generate(self, range)
}
}
pub unsafe trait CryptographicallySecure: PRNGenerator {}
pub trait Splittable: PRNGenerator {
#[must_use]
fn split(&mut self) -> Self;
}
#[derive(Debug)]
#[reprc]
pub struct DeserializationResult<T: ReprC> {
pub read_bytes: usize,
pub value: T,
}
pub trait PRNGSerialize: PRNGenerator {
type SerializeError: Into<SerializeError> + ReprC;
type DeserializeError: Into<DeserializeError> + ReprC;
const MAX_SERIALIZED_SIZE: usize;
fn serialize(&self, buffer: &mut [u8]) -> Result<usize, Self::SerializeError>;
fn deserialize(buffer: &[u8]) -> Result<DeserializationResult<Self>, Self::DeserializeError>;
}
pub trait PRStream: Sized + Clone + ReprC {
unsafe fn fill_raw(&mut self, dst_ptr: *mut u8, dst_len: usize);
#[inline(always)]
fn fill_block(&mut self, block: &mut [u8]) {
unsafe {
self.fill_raw(block.as_mut_ptr(), block.len());
}
}
#[inline(always)]
#[must_use]
fn next_block<const N: usize>(&mut self) -> [u8; N] {
let mut block = [0u8; N];
self.fill_block(&mut block);
block
}
}
pub trait Seedable<TSeed: ReprC + Copy> {
#[must_use]
fn with_seed(seed: TSeed) -> Self;
}