Skip to content

Commit

Permalink
Merge pull request #61 from moia-oss/rand-support-for-time-duration
Browse files Browse the repository at this point in the history
Random sampling of `Time` and `Duration`
  • Loading branch information
Felerius authored Apr 25, 2024
2 parents bd891d3 + d7c22c0 commit 9b05738
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 3 deletions.
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ edition = "2021"
version = "0.12.2"
license = "MIT OR Apache-2.0"

[features]
rand = ["dep:rand"]

[dependencies]
chrono = "0.4.31"
derive_more = "0.99.17"
lazy_static = "1.4.0"
rand = { version = "0.8.5", optional = true }
regex = "1.10.2"
serde = { version = "1.0.193", features = ["derive"], default-features = false }
thiserror = "1.0.50"
Expand Down Expand Up @@ -58,7 +62,7 @@ missing_const_for_fn = "warn"
### Pedantic
pedantic = { level = "warn", priority = -1 }
missing_errors_doc = "allow" # TODO
cast_precision_loss = "allow"
cast_precision_loss = "allow"
cast_possible_truncation = "allow"
cast_lossless = "allow"
cast_possible_wrap = "allow"
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tools/grcov/$(GRCOV_VERSION)/grcov:

.PHONY: test
test:
cargo test --workspace --all-targets
cargo test --workspace --all-targets --all-features
cargo test --workspace --doc

lint:
Expand Down Expand Up @@ -77,4 +77,4 @@ coverage-html: tools/grcov/$(GRCOV_VERSION)/grcov
--ignore-not-existing \
--keep-only=/src/**/*.rs \
-o ./coverage && \
open coverage/index.html
open coverage/index.html
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
//! let result: f64 = duration / duration; // | Duration | / | Duration | f64 |

//! ```
#[cfg(feature = "rand")]
pub mod rand;

use core::fmt;
use std::cmp::max;
use std::cmp::min;
Expand Down
135 changes: 135 additions & 0 deletions src/rand.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
use rand::distributions::uniform::SampleBorrow;
use rand::distributions::uniform::SampleUniform;
use rand::distributions::uniform::UniformInt;
use rand::distributions::uniform::UniformSampler;
use rand::distributions::Distribution;
use rand::distributions::Standard;
use rand::Rng;

use crate::Duration;
use crate::Time;

impl Distribution<Time> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Time {
Time(rng.gen())
}
}

#[derive(Debug, Clone, Copy)]
pub struct UniformTime(UniformInt<i64>);

impl UniformSampler for UniformTime {
type X = Time;

fn new<B1, B2>(low: B1, high: B2) -> Self
where
B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized,
{
Self(UniformInt::new(low.borrow().0, high.borrow().0))
}

fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
where
B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized,
{
Self(UniformInt::new_inclusive(low.borrow().0, high.borrow().0))
}

fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
Time(self.0.sample(rng))
}
}

impl SampleUniform for Time {
type Sampler = UniformTime;
}

impl Distribution<Duration> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Duration {
Duration(rng.gen())
}
}

#[derive(Debug, Clone, Copy)]
pub struct UniformDuration(UniformInt<i64>);

impl UniformSampler for UniformDuration {
type X = Duration;

fn new<B1, B2>(low: B1, high: B2) -> Self
where
B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized,
{
Self(UniformInt::new(low.borrow().0, high.borrow().0))
}

fn new_inclusive<B1, B2>(low: B1, high: B2) -> Self
where
B1: SampleBorrow<Self::X> + Sized,
B2: SampleBorrow<Self::X> + Sized,
{
Self(UniformInt::new_inclusive(low.borrow().0, high.borrow().0))
}

fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Self::X {
Duration(self.0.sample(rng))
}
}

impl SampleUniform for Duration {
type Sampler = UniformDuration;
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn standard_time() {
let _: Time = rand::random();
let _: Time = rand::thread_rng().gen();
}

#[test]
fn uniform_time() {
let mut rng = rand::thread_rng();
assert_eq!(Time::EPOCH, rng.gen_range(Time::EPOCH..Time::millis(1)));
assert_eq!(Time::EPOCH, rng.gen_range(Time::EPOCH..=Time::EPOCH));

let low = Time::millis(100);
let high = Time::millis(110);
for _ in 0..1000 {
let x = rng.gen_range(low..high);
assert!((low..high).contains(&x));
}
}

#[test]
fn standard_duration() {
let _: Duration = rand::random();
let _: Duration = rand::thread_rng().gen();
}

#[test]
fn uniform_duration() {
let mut rng = rand::thread_rng();
assert_eq!(
Duration::ZERO,
rng.gen_range(Duration::ZERO..Duration::millis(1))
);
assert_eq!(
Duration::ZERO,
rng.gen_range(Duration::ZERO..=Duration::ZERO)
);

let low = Duration::millis(100);
let high = Duration::millis(110);
for _ in 0..1000 {
let x = rng.gen_range(low..high);
assert!((low..high).contains(&x));
}
}
}

0 comments on commit 9b05738

Please sign in to comment.