use rand::{prelude::*, thread_rng};
use crate::entropy::Entropy;
use crate::prelude::*;
#[derive(Copy, Clone, Debug)]
pub enum Probability {
Always,
Sometimes(f64),
Never,
}
impl Probability {
pub fn from(probability: f64) -> Self {
match probability {
x if x >= 1.0 => Probability::Always,
x if x <= 0.0 => Probability::Never,
x => Probability::Sometimes(x),
}
}
pub fn from_percentage(percentage: f64) -> Self {
match percentage {
x if x >= 100.0 => Probability::Always,
x if x <= 0.0 => Probability::Never,
x => Probability::Sometimes(x / 100.0),
}
}
pub fn half() -> Self {
Self::from(0.5)
}
pub fn value(&self) -> f64 {
match self {
Probability::Always => 1.0,
Probability::Sometimes(p) => *p,
Probability::Never => 0.0,
}
}
pub fn percentage(&self) -> f64 {
self.value() * 100.0
}
pub fn gen_bool<R: Rng>(self, rng: &mut R) -> bool {
match self {
Probability::Always => true,
Probability::Never => false,
Probability::Sometimes(p) => rng.gen_bool(p),
}
}
pub fn gen_bool_secure(self) -> bool {
match self {
Probability::Always => true,
Probability::Never => false,
Probability::Sometimes(_) => self.gen_bool(&mut thread_rng()),
}
}
}
impl HasEntropy for Probability {
fn entropy(&self) -> Entropy {
match self {
Probability::Sometimes(_p) => Entropy::one(),
_ => Entropy::zero(),
}
}
}
impl From<bool> for Probability {
fn from(b: bool) -> Probability {
if b {
Probability::Always
} else {
Probability::Never
}
}
}