Skip to main content

time/
rand010.rs

1//! Implementation of [`Distribution`] for various structs.
2
3use rand010::distr::{Distribution, StandardUniform};
4use rand010::{Rng, RngExt as _};
5
6use crate::{
7    Date, Duration, Month, OffsetDateTime, PrimitiveDateTime, Time, Timestamp, UtcDateTime,
8    UtcOffset, Weekday,
9};
10
11impl Distribution<Time> for StandardUniform {
12    #[inline]
13    fn sample<R>(&self, rng: &mut R) -> Time
14    where
15        R: Rng + ?Sized,
16    {
17        Time::from_hms_nanos_ranged(rng.random(), rng.random(), rng.random(), rng.random())
18    }
19}
20
21impl Distribution<Date> for StandardUniform {
22    #[inline]
23    fn sample<R>(&self, rng: &mut R) -> Date
24    where
25        R: Rng + ?Sized,
26    {
27        // Safety: The Julian day number is in range.
28        unsafe {
29            Date::from_julian_day_unchecked(
30                rng.random_range(Date::MIN.to_julian_day()..=Date::MAX.to_julian_day()),
31            )
32        }
33    }
34}
35
36impl Distribution<UtcOffset> for StandardUniform {
37    #[inline]
38    fn sample<R>(&self, rng: &mut R) -> UtcOffset
39    where
40        R: Rng + ?Sized,
41    {
42        UtcOffset::from_hms_ranged(rng.random(), rng.random(), rng.random())
43    }
44}
45
46impl Distribution<PrimitiveDateTime> for StandardUniform {
47    #[inline]
48    fn sample<R>(&self, rng: &mut R) -> PrimitiveDateTime
49    where
50        R: Rng + ?Sized,
51    {
52        PrimitiveDateTime::new(Self.sample(rng), Self.sample(rng))
53    }
54}
55
56impl Distribution<UtcDateTime> for StandardUniform {
57    #[inline]
58    fn sample<R>(&self, rng: &mut R) -> UtcDateTime
59    where
60        R: Rng + ?Sized,
61    {
62        UtcDateTime::new(Self.sample(rng), Self.sample(rng))
63    }
64}
65
66impl Distribution<OffsetDateTime> for StandardUniform {
67    #[inline]
68    fn sample<R>(&self, rng: &mut R) -> OffsetDateTime
69    where
70        R: Rng + ?Sized,
71    {
72        let date_time: PrimitiveDateTime = Self.sample(rng);
73        date_time.assume_offset(Self.sample(rng))
74    }
75}
76
77impl Distribution<Timestamp> for StandardUniform {
78    #[inline]
79    fn sample<R>(&self, rng: &mut R) -> Timestamp
80    where
81        R: Rng + ?Sized,
82    {
83        Timestamp::new_ranged(rng.random(), rng.random())
84    }
85}
86
87impl Distribution<Duration> for StandardUniform {
88    #[inline]
89    fn sample<R>(&self, rng: &mut R) -> Duration
90    where
91        R: Rng + ?Sized,
92    {
93        Duration::new_ranged(rng.random(), rng.random())
94    }
95}
96
97impl Distribution<Weekday> for StandardUniform {
98    #[inline]
99    fn sample<R>(&self, rng: &mut R) -> Weekday
100    where
101        R: Rng + ?Sized,
102    {
103        use Weekday::*;
104
105        match rng.random_range(0u8..7) {
106            0 => Monday,
107            1 => Tuesday,
108            2 => Wednesday,
109            3 => Thursday,
110            4 => Friday,
111            5 => Saturday,
112            val => {
113                debug_assert!(val == 6);
114                Sunday
115            }
116        }
117    }
118}
119
120impl Distribution<Month> for StandardUniform {
121    #[inline]
122    fn sample<R>(&self, rng: &mut R) -> Month
123    where
124        R: Rng + ?Sized,
125    {
126        use Month::*;
127        match rng.random_range(1u8..=12) {
128            1 => January,
129            2 => February,
130            3 => March,
131            4 => April,
132            5 => May,
133            6 => June,
134            7 => July,
135            8 => August,
136            9 => September,
137            10 => October,
138            11 => November,
139            val => {
140                debug_assert!(val == 12);
141                December
142            }
143        }
144    }
145}