#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct RngState {
pub version: u32,
pub rng_type: String,
pub state_data: Vec<u8>,
}
impl RngState {
pub const CURRENT_VERSION: u32 = 1;
pub fn new(rng_type: String, state_data: Vec<u8>) -> Self {
Self {
version: Self::CURRENT_VERSION,
rng_type,
state_data,
}
}
pub fn is_compatible(&self) -> bool {
self.version == Self::CURRENT_VERSION
}
}
pub trait StatefulRng {
fn save_state(&self) -> RngState;
fn restore_state(&mut self, state: &RngState) -> crate::error::Result<()>;
}
#[cfg(feature = "fast_rng")]
impl crate::fast::xoshiro256::Xoshiro256Plus {
#[cfg(feature = "serde")]
pub fn serialize_state(&self) -> Result<Vec<u8>, serde_json::Error> {
let state = self.save_state();
serde_json::to_vec(&state)
}
#[cfg(feature = "serde")]
pub fn deserialize_state(data: &[u8]) -> Result<Self, serde_json::Error> {
let state: [u64; 4] = serde_json::from_slice(data)?;
let mut rng = Self::new(0);
rng.restore_state(state);
Ok(rng)
}
}
#[cfg(feature = "fast_rng")]
impl crate::fast::pcg64::Pcg64 {
#[cfg(feature = "serde")]
pub fn serialize_state(&self) -> Result<Vec<u8>, serde_json::Error> {
let state = self.save_state();
serde_json::to_vec(&state)
}
#[cfg(feature = "serde")]
pub fn deserialize_state(data: &[u8]) -> Result<Self, serde_json::Error> {
let state: [u64; 2] = serde_json::from_slice(data)?;
let mut rng = Self::new(0);
rng.restore_state(state);
Ok(rng)
}
}
#[cfg(test)]
#[cfg(feature = "serde")]
mod tests {
use crate::fast::xoshiro256::Xoshiro256Plus;
#[test]
fn test_rng_state_serialization() {
let rng = Xoshiro256Plus::new(42);
let state = rng.save_state();
let serialized = serde_json::to_string(&state).unwrap();
let deserialized: [u64; 4] = serde_json::from_str(&serialized).unwrap();
assert_eq!(state, deserialized);
}
}