parse_frequency/
time.rs

1use crate::Frequency;
2
3impl Frequency {
4    /// Converts the frequency to a `time::Duration`.
5    ///
6    /// # Examples
7    /// ```rust
8    /// use parse_frequency::Frequency;
9    ///
10    /// let freq = Frequency::from_ghz(1);
11    /// let duration = freq.as_time_duration();
12    /// assert_eq!(duration.whole_nanoseconds(), 1);
13    ///
14    /// let freq = Frequency::from_mhz(1);
15    /// let duration = freq.as_time_duration();
16    /// assert_eq!(duration.whole_nanoseconds(), 1_000);
17    /// ```
18    #[must_use]
19    #[allow(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
20    pub fn as_time_duration(&self) -> time::Duration {
21        if self.0 == 0 {
22            return time::Duration::ZERO;
23        }
24
25        let nanoseconds_per_second: u64 = crate::GIGAHERTZ;
26
27        // Calculate the period in nanoseconds.
28        // To avoid potential overflow if self.0 is small, we perform the division last.
29        if nanoseconds_per_second >= self.0 {
30            time::Duration::nanoseconds((nanoseconds_per_second / self.0) as i64)
31        } else {
32            // If frequency is higher than 1 GHz, the period is less than 1 ns.
33            // We need to handle this carefully. We can calculate the reciprocal
34            // as a fraction and then convert to nanoseconds, potentially losing
35            // some precision for extremely high frequencies.
36            let picoseconds_per_second: u128 = 1_000_000_000_000;
37            let frequency: u128 = u128::from(self.0);
38            let period_in_picoseconds = picoseconds_per_second / frequency;
39
40            // Convert picoseconds to nanoseconds (integer division will truncate)
41            let period_in_nanoseconds = period_in_picoseconds / 1_000;
42            time::Duration::nanoseconds(period_in_nanoseconds as i64)
43        }
44    }
45}