use clap::{Args, ValueEnum};
use rand_chacha::ChaCha20Rng;
use rand_core::{CryptoRngCore, SeedableRng};
use rand_hc::Hc128Rng;
use rand_seeder::Seeder;
#[derive(Debug, Clone, Default, clap::Args, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[group(id = "rng")]
#[remain::sorted]
#[rustfmt::skip]
pub(crate) struct RngOptions {
#[arg(
env = "RNG_ALGORITHM",
long = "rng-algorithm",
id = "rng.algorithm",
value_name = "ALGORITHM",
default_value = "chacha20",
help_heading = "RNG Options",
)]
pub(crate) algorithm: RngAlgorithm,
#[arg(
env = "RNG_SEED",
long = "rng-seed",
id = "rng.seed",
value_name = "STRING",
help_heading = "RNG Options",
)]
pub(crate) seed: Option<String>,
}
#[derive(Debug, Clone, Copy, Default, clap::ValueEnum, serde::Deserialize, serde::Serialize, schemars::JsonSchema)]
#[clap(rename_all = "lowercase")]
#[remain::sorted]
pub(crate) enum RngAlgorithm {
#[default]
ChaCha20,
Hc128,
}
impl RngOptions {
pub(crate) fn to_crypto_rng(&self) -> Box<dyn CryptoRngCore> {
let Self { algorithm, seed } = self;
match algorithm {
RngAlgorithm::ChaCha20 => Box::new(match seed {
Some(seed) => Seeder::from(&seed).make_rng(),
None => ChaCha20Rng::from_entropy(),
}),
RngAlgorithm::Hc128 => Box::new(match seed {
Some(seed) => Seeder::from(&seed).make_rng(),
None => Hc128Rng::from_entropy(),
}),
}
}
}