diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2838c3229..4945f5e8390 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update. ## [Unreleased] ### Additions - Use const-generics to support arrays of all sizes (#1104) +- Implement `Clone` and `Copy` for `Alphanumeric` (#1126) ### Other - Reorder asserts in `Uniform` float distributions for easier debugging of non-finite arguments diff --git a/rand_distr/CHANGELOG.md b/rand_distr/CHANGELOG.md index 05cd23f59f8..346be3c26bb 100644 --- a/rand_distr/CHANGELOG.md +++ b/rand_distr/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Correctly document `no_std` support (#1100) - Add `std_math` feature to prefer `std` over `libm` for floating point math (#1100) - Add mean and std_dev accessors to Normal (#1114) +- Make sure all distributions and their error types implement `Error`, `Display`, `Clone`, + `Copy`, `PartialEq` and `Eq` as appropriate (#1126) ## [0.4.0] - 2020-12-18 - Bump `rand` to v0.8.0 diff --git a/rand_distr/src/hypergeometric.rs b/rand_distr/src/hypergeometric.rs index 512dd34c19b..507d7bb07f5 100644 --- a/rand_distr/src/hypergeometric.rs +++ b/rand_distr/src/hypergeometric.rs @@ -73,6 +73,10 @@ impl fmt::Display for Error { } } +#[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +impl std::error::Error for Error {} + // evaluate fact(numerator.0)*fact(numerator.1) / fact(denominator.0)*fact(denominator.1) fn fraction_of_products_of_factorials(numerator: (u64, u64), denominator: (u64, u64)) -> f64 { let min_top = u64::min(numerator.0, numerator.1); diff --git a/rand_distr/src/inverse_gaussian.rs b/rand_distr/src/inverse_gaussian.rs index 7af645a23c4..becb02b64f8 100644 --- a/rand_distr/src/inverse_gaussian.rs +++ b/rand_distr/src/inverse_gaussian.rs @@ -1,9 +1,10 @@ use crate::{Distribution, Standard, StandardNormal}; use num_traits::Float; use rand::Rng; +use core::fmt; /// Error type returned from `InverseGaussian::new` -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { /// `mean <= 0` or `nan`. MeanNegativeOrNull, @@ -11,8 +12,21 @@ pub enum Error { ShapeNegativeOrNull, } +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Error::MeanNegativeOrNull => "mean <= 0 or is NaN in inverse Gaussian distribution", + Error::ShapeNegativeOrNull => "shape <= 0 or is NaN in inverse Gaussian distribution", + }) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +impl std::error::Error for Error {} + /// The [inverse Gaussian distribution](https://en.wikipedia.org/wiki/Inverse_Gaussian_distribution) -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct InverseGaussian where F: Float, diff --git a/rand_distr/src/normal_inverse_gaussian.rs b/rand_distr/src/normal_inverse_gaussian.rs index 252a319d877..d8e44587d05 100644 --- a/rand_distr/src/normal_inverse_gaussian.rs +++ b/rand_distr/src/normal_inverse_gaussian.rs @@ -1,9 +1,10 @@ use crate::{Distribution, InverseGaussian, Standard, StandardNormal}; use num_traits::Float; use rand::Rng; +use core::fmt; /// Error type returned from `NormalInverseGaussian::new` -#[derive(Debug, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Error { /// `alpha <= 0` or `nan`. AlphaNegativeOrNull, @@ -11,8 +12,21 @@ pub enum Error { AbsoluteBetaNotLessThanAlpha, } +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Error::AlphaNegativeOrNull => "alpha <= 0 or is NaN in normal inverse Gaussian distribution", + Error::AbsoluteBetaNotLessThanAlpha => "|beta| >= alpha or is NaN in normal inverse Gaussian distribution", + }) + } +} + +#[cfg(feature = "std")] +#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))] +impl std::error::Error for Error {} + /// The [normal-inverse Gaussian distribution](https://en.wikipedia.org/wiki/Normal-inverse_Gaussian_distribution) -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct NormalInverseGaussian where F: Float, diff --git a/src/distributions/other.rs b/src/distributions/other.rs index 9e58afd46e0..d1f060f483d 100644 --- a/src/distributions/other.rs +++ b/src/distributions/other.rs @@ -57,7 +57,7 @@ use std::mem::{self, MaybeUninit}; /// /// - [Wikipedia article on Password Strength](https://en.wikipedia.org/wiki/Password_strength) /// - [Diceware for generating memorable passwords](https://en.wikipedia.org/wiki/Diceware) -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))] pub struct Alphanumeric; diff --git a/src/distributions/weighted_index.rs b/src/distributions/weighted_index.rs index 07ba53ec027..32da37f6cd3 100644 --- a/src/distributions/weighted_index.rs +++ b/src/distributions/weighted_index.rs @@ -439,15 +439,15 @@ pub enum WeightedError { } #[cfg(feature = "std")] -impl ::std::error::Error for WeightedError {} +impl std::error::Error for WeightedError {} impl fmt::Display for WeightedError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - WeightedError::NoItem => write!(f, "No weights provided."), - WeightedError::InvalidWeight => write!(f, "A weight is invalid."), - WeightedError::AllWeightsZero => write!(f, "All weights are zero."), - WeightedError::TooMany => write!(f, "Too many weights (hit u32::MAX)"), - } + f.write_str(match *self { + WeightedError::NoItem => "No weights provided in distribution", + WeightedError::InvalidWeight => "A weight is invalid in distribution", + WeightedError::AllWeightsZero => "All weights are zero in distribution", + WeightedError::TooMany => "Too many weights (hit u32::MAX) in distribution", + }) } }