-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathtime.rs
More file actions
82 lines (74 loc) · 2.28 KB
/
time.rs
File metadata and controls
82 lines (74 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use super::{BasicGenerator, Generator, TestCase};
use crate::cbor_utils::cbor_map;
use std::time::Duration;
/// Generator for [`Duration`] values. Created by [`durations()`].
///
/// Internally generates nanoseconds as a `u64`, so the maximum representable
/// duration is approximately 584 years (`u64::MAX` nanoseconds).
/// Use `min_value` and `max_value` to constrain the range.
pub struct DurationGenerator {
min_nanos: u64,
max_nanos: u64,
}
impl DurationGenerator {
/// Set the minimum duration (inclusive).
pub fn min_value(mut self, min: Duration) -> Self {
self.min_nanos = duration_to_nanos(min);
self
}
/// Set the maximum duration (inclusive).
pub fn max_value(mut self, max: Duration) -> Self {
self.max_nanos = duration_to_nanos(max);
self
}
fn build_schema(&self) -> ciborium::Value {
assert!(
self.min_nanos <= self.max_nanos,
"Cannot have max_value < min_value"
);
cbor_map! {
"type" => "integer",
"min_value" => self.min_nanos,
"max_value" => self.max_nanos
}
}
}
impl Generator<Duration> for DurationGenerator {
fn do_draw(&self, tc: &TestCase) -> Duration {
let nanos: u64 = super::generate_from_schema(tc, &self.build_schema());
Duration::from_nanos(nanos)
}
fn as_basic(&self) -> Option<BasicGenerator<'_, Duration>> {
Some(BasicGenerator::new(self.build_schema(), |raw| {
let nanos: u64 = super::deserialize_value(raw);
Duration::from_nanos(nanos)
}))
}
}
/// Generate [`Duration`] values.
///
/// By default, generates durations from zero up to `u64::MAX` nanoseconds
/// (approximately 584 years). Use `min_value` and `max_value` to constrain
/// the range.
///
/// # Example
///
/// ```no_run
/// use std::time::Duration;
///
/// #[hegel::test]
/// fn my_test(tc: hegel::TestCase) {
/// let d = tc.draw(hegel::generators::durations()
/// .max_value(Duration::from_secs(60)));
/// assert!(d <= Duration::from_secs(60));
/// }
/// ```
pub fn durations() -> DurationGenerator {
DurationGenerator {
min_nanos: 0,
max_nanos: u64::MAX,
}
}
fn duration_to_nanos(d: Duration) -> u64 {
d.as_nanos().try_into().unwrap_or(u64::MAX)
}