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
83
84
85
86
87
88
89
use crate::{Driver, TypeGenerator, TypeGeneratorWithParams, TypeValueGenerator, ValueGenerator};
use core::{ops::Range, time::Duration};

pub struct DurationGenerator<Seconds, Nanos> {
    seconds: Seconds,
    nanos: Nanos,
}

const VALID_NANOS_RANGE: Range<u32> = 0..1_000_000_000;

impl<Seconds, Nanos> DurationGenerator<Seconds, Nanos>
where
    Seconds: ValueGenerator<Output = u64>,
    Nanos: ValueGenerator<Output = u32>,
{
    pub fn seconds<NewS: ValueGenerator<Output = u64>>(
        self,
        seconds: NewS,
    ) -> DurationGenerator<NewS, Nanos> {
        DurationGenerator {
            seconds,
            nanos: self.nanos,
        }
    }

    pub fn map_seconds<NewS: ValueGenerator<Output = u64>, F: Fn(Seconds) -> NewS>(
        self,
        map: F,
    ) -> DurationGenerator<NewS, Nanos> {
        DurationGenerator {
            seconds: map(self.seconds),
            nanos: self.nanos,
        }
    }

    pub fn nanos<NewE: ValueGenerator<Output = u32>>(
        self,
        nanos: NewE,
    ) -> DurationGenerator<Seconds, NewE> {
        DurationGenerator {
            seconds: self.seconds,
            nanos,
        }
    }

    pub fn map_nanos<NewE: ValueGenerator<Output = u64>, F: Fn(Nanos) -> NewE>(
        self,
        map: F,
    ) -> DurationGenerator<Seconds, NewE> {
        DurationGenerator {
            seconds: self.seconds,
            nanos: map(self.nanos),
        }
    }
}

impl<Seconds, Nanos> ValueGenerator for DurationGenerator<Seconds, Nanos>
where
    Seconds: ValueGenerator<Output = u64>,
    Nanos: ValueGenerator<Output = u32>,
{
    type Output = Duration;

    fn generate<D: Driver>(&self, driver: &mut D) -> Option<Self::Output> {
        let seconds = self.seconds.generate(driver)?;
        let nanos = self.nanos.generate(driver)?;
        Some(Duration::new(seconds, nanos))
    }
}

impl TypeGenerator for Duration {
    fn generate<D: Driver>(driver: &mut D) -> Option<Self> {
        Some(Self::new(
            driver.gen()?,
            VALID_NANOS_RANGE.generate(driver)?,
        ))
    }
}

impl TypeGeneratorWithParams for Duration {
    type Output = DurationGenerator<TypeValueGenerator<u64>, Range<u32>>;

    fn gen_with() -> Self::Output {
        DurationGenerator {
            seconds: Default::default(),
            nanos: VALID_NANOS_RANGE,
        }
    }
}