]> git.lizzy.rs Git - rust.git/commitdiff
Add missing Debug implementation for librand structs
authorGuillaume Gomez <guillaume1.gomez@gmail.com>
Wed, 18 Jan 2017 16:13:47 +0000 (17:13 +0100)
committerGuillaume Gomez <guillaume1.gomez@gmail.com>
Wed, 18 Jan 2017 16:13:47 +0000 (17:13 +0100)
src/librand/chacha.rs
src/librand/distributions/exponential.rs
src/librand/distributions/gamma.rs
src/librand/distributions/mod.rs
src/librand/distributions/normal.rs
src/librand/distributions/range.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librand/reseeding.rs

index 7dc0d19e6a615cd32e04e869ff89a978d1fa2df1..e355eb44e4667f292e4265e9393e09c07d13b5a4 100644 (file)
@@ -10,6 +10,7 @@
 
 //! The ChaCha random number generator.
 
+use core::fmt;
 use {Rand, Rng, SeedableRng};
 
 const KEY_WORDS: usize = 8; // 8 words for the 256-bit key
@@ -32,6 +33,16 @@ pub struct ChaChaRng {
     index: usize, // Index into state
 }
 
+impl fmt::Debug for ChaChaRng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("ChaChaRng")
+         .field("buffer", &self.buffer.iter())
+         .field("state", &self.state.iter())
+         .field("index", &self.index)
+         .finish()
+    }
+}
+
 static EMPTY: ChaChaRng = ChaChaRng {
     buffer: [0; STATE_WORDS],
     state: [0; STATE_WORDS],
index 5a8558efc024437b82300161ec3133c147795a8a..3337cc2a6273cf78731a7ad12b3f2ef46e91b543 100644 (file)
@@ -10,6 +10,8 @@
 
 //! The exponential distribution.
 
+use core::fmt;
+
 #[cfg(not(test))] // only necessary for no_std
 use FloatMath;
 
@@ -55,6 +57,14 @@ fn zero_case<R: Rng>(rng: &mut R, _u: f64) -> f64 {
     }
 }
 
+impl fmt::Debug for Exp1 {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Exp1")
+         .field(&self.0)
+         .finish()
+    }
+}
+
 /// The exponential distribution `Exp(lambda)`.
 ///
 /// This distribution has density function: `f(x) = lambda *
@@ -79,6 +89,7 @@ fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for Exp {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         let Exp1(n) = rng.gen::<Exp1>();
@@ -86,6 +97,14 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
     }
 }
 
+impl fmt::Debug for Exp {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Exp")
+         .field("lambda_inverse", &self.lambda_inverse)
+         .finish()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use distributions::{IndependentSample, Sample};
index 9ca13e85b533304f2f2c5c7bc5657da138556343..e024b62adfb15c4756b395215e7abead5016e77c 100644 (file)
@@ -10,6 +10,8 @@
 
 //! The Gamma and derived distributions.
 
+use core::fmt;
+
 use self::GammaRepr::*;
 use self::ChiSquaredRepr::*;
 
@@ -44,6 +46,19 @@ pub struct Gamma {
     repr: GammaRepr,
 }
 
+impl fmt::Debug for Gamma {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Gamma")
+         .field("repr",
+                &match self.repr {
+                    GammaRepr::Large(_) => "Large",
+                    GammaRepr::One(_) => "Exp",
+                    GammaRepr::Small(_) => "Small"
+                })
+          .finish()
+    }
+}
+
 enum GammaRepr {
     Large(GammaLargeShape),
     One(Exp),
@@ -182,6 +197,18 @@ pub struct ChiSquared {
     repr: ChiSquaredRepr,
 }
 
+impl fmt::Debug for ChiSquared {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("ChiSquared")
+         .field("repr",
+                &match self.repr {
+                    ChiSquaredRepr::DoFExactlyOne => "DoFExactlyOne",
+                    ChiSquaredRepr::DoFAnythingElse(_) => "DoFAnythingElse",
+                })
+         .finish()
+    }
+}
+
 enum ChiSquaredRepr {
     // k == 1, Gamma(alpha, ..) is particularly slow for alpha < 1,
     // e.g. when alpha = 1/2 as it would be for this case, so special-
@@ -203,11 +230,13 @@ pub fn new(k: f64) -> ChiSquared {
         ChiSquared { repr: repr }
     }
 }
+
 impl Sample<f64> for ChiSquared {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for ChiSquared {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         match self.repr {
@@ -248,17 +277,29 @@ pub fn new(m: f64, n: f64) -> FisherF {
         }
     }
 }
+
 impl Sample<f64> for FisherF {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for FisherF {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         self.numer.ind_sample(rng) / self.denom.ind_sample(rng) * self.dof_ratio
     }
 }
 
+impl fmt::Debug for FisherF {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("FisherF")
+         .field("numer", &self.numer)
+         .field("denom", &self.denom)
+         .field("dof_ratio", &self.dof_ratio)
+         .finish()
+    }
+}
+
 /// The Student t distribution, `t(nu)`, where `nu` is the degrees of
 /// freedom.
 pub struct StudentT {
@@ -277,11 +318,13 @@ pub fn new(n: f64) -> StudentT {
         }
     }
 }
+
 impl Sample<f64> for StudentT {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for StudentT {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         let StandardNormal(norm) = rng.gen::<StandardNormal>();
@@ -289,6 +332,15 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
     }
 }
 
+impl fmt::Debug for StudentT {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("StudentT")
+         .field("chi", &self.chi)
+         .field("dof", &self.dof)
+         .finish()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use distributions::{IndependentSample, Sample};
index 41175c81df8918bbd5302e8f816296ab150a01f9..fb0c9f17cf36737e78f8cd39501b6115800b1ea5 100644 (file)
@@ -17,6 +17,8 @@
 //! internally. The `IndependentSample` trait is for generating values
 //! that do not need to record state.
 
+use core::fmt;
+
 #[cfg(not(test))] // only necessary for no_std
 use core::num::Float;
 
@@ -78,6 +80,12 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
     }
 }
 
+impl<Sup> fmt::Debug for RandSample<Sup> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("RandSample { .. }")
+    }
+}
+
 /// A value with a particular weight for use with `WeightedChoice`.
 pub struct Weighted<T> {
     /// The numerical weight of this item
@@ -86,6 +94,21 @@ pub struct Weighted<T> {
     pub item: T,
 }
 
+impl<T> fmt::Debug for Weighted<T> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Weighted")
+    }
+}
+
+impl<T: fmt::Debug> fmt::Debug for Weighted<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Weighted")
+         .field("weight", &self.weight)
+         .field("item", &self.item)
+         .finish()
+    }
+}
+
 /// A distribution that selects from a finite collection of weighted items.
 ///
 /// Each item has an associated weight that influences how likely it
@@ -189,6 +212,21 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> T {
     }
 }
 
+impl<'a, T> fmt::Debug for WeightedChoice<'a, T> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("WeightedChoice")
+    }
+}
+
+impl<'a, T: fmt::Debug> fmt::Debug for WeightedChoice<'a, T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("WeightedChoice")
+         .field("items", &self.items)
+         .field("weight_range", &self.weight_range)
+         .finish()
+    }
+}
+
 mod ziggurat_tables;
 
 /// Sample a random number using the Ziggurat method (specifically the
index 811d5b14c71129c40bd51f580e53c02d463fcfd0..33de11ab63087c766e7534706bf53c92ae6f2610 100644 (file)
@@ -10,6 +10,8 @@
 
 //! The normal and derived distributions.
 
+use core::fmt;
+
 #[cfg(not(test))] // only necessary for no_std
 use FloatMath;
 
@@ -73,6 +75,14 @@ fn zero_case<R: Rng>(rng: &mut R, u: f64) -> f64 {
     }
 }
 
+impl fmt::Debug for StandardNormal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("StandardNormal")
+         .field(&self.0)
+         .finish()
+    }
+}
+
 /// The normal distribution `N(mean, std_dev**2)`.
 ///
 /// This uses the ZIGNOR variant of the Ziggurat method, see
@@ -98,11 +108,13 @@ pub fn new(mean: f64, std_dev: f64) -> Normal {
         }
     }
 }
+
 impl Sample<f64> for Normal {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for Normal {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         let StandardNormal(n) = rng.gen::<StandardNormal>();
@@ -110,6 +122,15 @@ fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
     }
 }
 
+impl fmt::Debug for Normal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Normal")
+         .field("mean", &self.mean)
+         .field("std_dev", &self.std_dev)
+         .finish()
+    }
+}
+
 
 /// The log-normal distribution `ln N(mean, std_dev**2)`.
 ///
@@ -132,17 +153,27 @@ pub fn new(mean: f64, std_dev: f64) -> LogNormal {
         LogNormal { norm: Normal::new(mean, std_dev) }
     }
 }
+
 impl Sample<f64> for LogNormal {
     fn sample<R: Rng>(&mut self, rng: &mut R) -> f64 {
         self.ind_sample(rng)
     }
 }
+
 impl IndependentSample<f64> for LogNormal {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> f64 {
         self.norm.ind_sample(rng).exp()
     }
 }
 
+impl fmt::Debug for LogNormal {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("LogNormal")
+         .field("norm", &self.norm)
+         .finish()
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use distributions::{IndependentSample, Sample};
index ba8554a979b899309a3ebae5f4a1a869a1ddcf64..0df876fb16f34a11b8b4c63cc46eae00c82af5e6 100644 (file)
@@ -12,6 +12,7 @@
 
 // this is surprisingly complicated to be both generic & correct
 
+use core::fmt;
 use core::marker::Sized;
 use Rng;
 use distributions::{IndependentSample, Sample};
@@ -50,12 +51,29 @@ fn sample<R: Rng>(&mut self, rng: &mut R) -> Sup {
         self.ind_sample(rng)
     }
 }
+
 impl<Sup: SampleRange> IndependentSample<Sup> for Range<Sup> {
     fn ind_sample<R: Rng>(&self, rng: &mut R) -> Sup {
         SampleRange::sample_range(self, rng)
     }
 }
 
+impl<X> fmt::Debug for Range<X> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Range { .. }")
+    }
+}
+
+impl<X: fmt::Debug> fmt::Debug for Range<X> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Range")
+         .field("low", &self.low)
+         .field("range", &self.range)
+         .field("accept_zone", &self.accept_zone)
+         .finish()
+    }
+}
+
 /// The helper trait for types that have a sensible way to sample
 /// uniformly between two values. This should not be used directly,
 /// and is only to facilitate `Range`.
index 69d5015f18140153a339df182a1789f66ada22c8..2baa07e370e1740c775ee5ceabf57ab87fd4fbea 100644 (file)
@@ -12,6 +12,7 @@
 
 #![allow(non_camel_case_types)]
 
+use core::fmt;
 use core::slice;
 use core::iter::repeat;
 use core::num::Wrapping as w;
@@ -44,6 +45,19 @@ pub struct IsaacRng {
     c: w32,
 }
 
+impl fmt::Debug for IsaacRng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("IsaacRng")
+         .field("cnt", &self.cnt)
+         .field("rsl", &self.rsl.iter())
+         .field("mem", &self.mem.iter())
+         .field("a", &self.a)
+         .field("b", &self.b)
+         .field("c", &self.c)
+         .finish()
+    }
+}
+
 static EMPTY: IsaacRng = IsaacRng {
     cnt: 0,
     rsl: [w(0); RAND_SIZE_USIZE],
@@ -322,6 +336,19 @@ pub struct Isaac64Rng {
     c: w64,
 }
 
+impl fmt::Debug for Isaac64Rng {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Isaac64Rng")
+         .field("cnt", &self.cnt)
+         .field("rsl", &self.rsl.iter())
+         .field("mem", &self.mem.iter())
+         .field("a", &self.a)
+         .field("b", &self.b)
+         .field("c", &self.c)
+         .finish()
+    }
+}
+
 static EMPTY_64: Isaac64Rng = Isaac64Rng {
     cnt: 0,
     rsl: [w(0); RAND_SIZE_64],
index 0cf70880d328ba0fb61bdab3add134c1d2a569f5..888f0bc9b5547de9d9fbe9f314c0d4edc3cb2169 100644 (file)
@@ -24,6 +24,7 @@
        html_playground_url = "https://play.rust-lang.org/",
        test(attr(deny(warnings))))]
 #![deny(warnings)]
+#![deny(missing_debug_implementations)]
 #![no_std]
 #![unstable(feature = "rand",
             reason = "use `rand` from crates.io",
@@ -32,6 +33,7 @@
 #![feature(staged_api)]
 #![feature(step_by)]
 #![feature(custom_attribute)]
+#![feature(specialization)]
 #![allow(unused_attributes)]
 
 #![cfg_attr(not(test), feature(core_float))] // only necessary for no_std
@@ -43,6 +45,7 @@
 #[macro_use]
 extern crate std;
 
+use core::fmt;
 use core::f64;
 use core::intrinsics;
 use core::marker::PhantomData;
@@ -288,6 +291,20 @@ fn next(&mut self) -> Option<T> {
     }
 }
 
+impl<'a, T, R> fmt::Debug for Generator<'a, T, R> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Generator { .. }")
+    }
+}
+
+impl<'a, T, R: fmt::Debug> fmt::Debug for Generator<'a, T, R> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("Generator")
+         .field("rng", &self.rng)
+         .finish()
+    }
+}
+
 /// Iterator which will continuously generate random ascii characters.
 ///
 /// This iterator is created via the `gen_ascii_chars` method on `Rng`.
@@ -306,6 +323,20 @@ fn next(&mut self) -> Option<char> {
     }
 }
 
+impl<'a, R> fmt::Debug for AsciiGenerator<'a, R> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("AsciiGenerator { .. }")
+    }
+}
+
+impl<'a, R: fmt::Debug> fmt::Debug for AsciiGenerator<'a, R> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("AsciiGenerator")
+         .field("rng", &self.rng)
+         .finish()
+    }
+}
+
 /// A random number generator that can be explicitly seeded to produce
 /// the same stream of randomness multiple times.
 pub trait SeedableRng<Seed>: Rng {
@@ -326,7 +357,7 @@ pub trait SeedableRng<Seed>: Rng {
 /// [1]: Marsaglia, George (July 2003). ["Xorshift
 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
 /// Statistical Software*. Vol. 8 (Issue 14).
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct XorShiftRng {
     x: u32,
     y: u32,
@@ -415,6 +446,20 @@ fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
 /// `[0,1)`.
 pub struct Open01<F>(pub F);
 
+impl<F> fmt::Debug for Open01<F> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Open01 { .. }")
+    }
+}
+
+impl<F: fmt::Debug> fmt::Debug for Open01<F> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Open01")
+         .field(&self.0)
+         .finish()
+    }
+}
+
 /// A wrapper for generating floating point numbers uniformly in the
 /// closed interval `[0,1]` (including both endpoints).
 ///
@@ -423,6 +468,20 @@ fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
 /// `[0,1)`.
 pub struct Closed01<F>(pub F);
 
+impl<F> fmt::Debug for Closed01<F> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("Closed01 { .. }")
+    }
+}
+
+impl<F: fmt::Debug> fmt::Debug for Closed01<F> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_tuple("Closed01")
+         .field(&self.0)
+         .finish()
+    }
+}
+
 #[cfg(test)]
 mod test {
     use std::__rand as rand;
index b8a65842e2ff59388c52a938edd22372ca62a117..89ed53f76a15cdecbfdafcccb99a35625f36a220 100644 (file)
@@ -11,6 +11,7 @@
 //! A wrapper around another RNG that reseeds it after it
 //! generates a certain number of random bytes.
 
+use core::fmt;
 use {Rng, SeedableRng};
 
 /// How many bytes of entropy the underling RNG is allowed to generate
@@ -54,7 +55,6 @@ pub fn reseed_if_necessary(&mut self) {
     }
 }
 
-
 impl<R: Rng, Rsdr: Reseeder<R>> Rng for ReseedingRng<R, Rsdr> {
     fn next_u32(&mut self) -> u32 {
         self.reseed_if_necessary();
@@ -95,6 +95,23 @@ fn from_seed((rsdr, seed): (Rsdr, S)) -> ReseedingRng<R, Rsdr> {
     }
 }
 
+impl<R, Rsdr> fmt::Debug for ReseedingRng<R, Rsdr> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.pad("ReseedingRng { .. }")
+    }
+}
+
+impl<R: fmt::Debug, Rsdr: fmt::Debug> fmt::Debug for ReseedingRng<R, Rsdr> {
+    default fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        f.debug_struct("ReseedingRng")
+         .field("rng", &self.rng)
+         .field("generation_threshold", &self.generation_threshold)
+         .field("bytes_generated", &self.bytes_generated)
+         .field("reseeder", &self.reseeder)
+         .finish()
+    }
+}
+
 /// Something that can be used to reseed an RNG via `ReseedingRng`.
 pub trait Reseeder<R> {
     /// Reseed the given RNG.
@@ -103,7 +120,7 @@ pub trait Reseeder<R> {
 
 /// Reseed an RNG using a `Default` instance. This reseeds by
 /// replacing the RNG with the result of a `Default::default` call.
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug)]
 pub struct ReseedWithDefault;
 
 impl<R: Rng + Default> Reseeder<R> for ReseedWithDefault {