skytool 0.1.0-pre.2

an experimental API client for BlueSky / ATProto
Documentation
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(),
      }),
    }
  }
}