#[cfg(feature = "rand")]
use rand::{
distr::{Distribution, StandardUniform},
Rng,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)]
#[repr(transparent)]
pub struct Brightness(u8);
impl From<Brightness> for u8 {
fn from(brightness: Brightness) -> Self {
Self::from(&brightness)
}
}
impl From<&Brightness> for u8 {
fn from(brightness: &Brightness) -> Self {
brightness.0
}
}
impl TryFrom<u8> for Brightness {
type Error = u8;
fn try_from(value: u8) -> Result<Self, Self::Error> {
if value > Self::MAX.0 {
Err(value)
} else {
Ok(Brightness(value))
}
}
}
impl Brightness {
pub const MAX: Brightness = Brightness(11);
pub const MIN: Brightness = Brightness(0);
#[must_use]
pub fn saturating_from(value: u8) -> Brightness {
if value > Brightness::MAX.into() {
Brightness::MAX
} else {
Brightness(value)
}
}
}
impl Default for Brightness {
fn default() -> Self {
Self::MAX
}
}
#[cfg(feature = "rand")]
impl Distribution<Brightness> for StandardUniform {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Brightness {
Brightness(rng.random_range(Brightness::MIN.0..=Brightness::MAX.0))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn brightness_from_u8() {
assert_eq!(Err(100), Brightness::try_from(100));
assert_eq!(Ok(Brightness(1)), Brightness::try_from(1));
}
#[test]
#[cfg(feature = "rand")]
fn rand_brightness() {
let mut rng = rand::rng();
for _ in 0..100 {
let _: Brightness = rng.random();
}
}
#[test]
fn saturating_convert() {
assert_eq!(Brightness::MAX, Brightness::saturating_from(100));
assert_eq!(Brightness(5), Brightness::saturating_from(5));
}
#[test]
#[cfg(feature = "rand")]
fn test() {
let mut rng = rand::rng();
assert_ne!(
[
rng.random::<Brightness>(),
rng.random(),
rng.random(),
rng.random()
],
[rng.random(), rng.random(), rng.random(), rng.random()]
);
}
}