libpulse_binding/time/
monotonic.rs

1// Copyright 2018 Lyndon Brown
2//
3// This file is part of the PulseAudio Rust language binding.
4//
5// Licensed under the MIT license or the Apache license (version 2.0), at your option. You may not
6// copy, modify, or distribute this file except in compliance with said license. You can find copies
7// of these licenses either in the LICENSE-MIT and LICENSE-APACHE files, or alternatively at
8// <http://opensource.org/licenses/MIT> and <http://www.apache.org/licenses/LICENSE-2.0>
9// respectively.
10//
11// Portions of documentation are copied from the LGPL 2.1+ licensed PulseAudio C headers on a
12// fair-use basis, as discussed in the overall project readme (available in the git repository).
13
14//! Monotonic timestamps.
15
16use std::ops::{Add, AddAssign, Sub, SubAssign};
17use std::time::Duration;
18use super::{MicroSeconds, op_err};
19
20/// A monotonic timestamp.
21#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
22pub struct MonotonicTs(pub(crate) MicroSeconds);
23
24impl MonotonicTs {
25    /// Gets the current monotonic system time in microseconds.
26    ///
27    /// Note, if such a clock is not available then this will actually fall back to the wallclock
28    /// time instead. No indication is available for whether or not this is the case, and the
29    /// return value is still a `MonotonicTs` type.
30    #[inline]
31    pub fn now() -> Self {
32        Self(MicroSeconds(unsafe { capi::pa_rtclock_now() }))
33    }
34
35    /// Returns `true` so long as inner value is not [`MicroSeconds::INVALID`].
36    #[inline]
37    pub fn is_valid(&self) -> bool {
38        self.0.is_valid()
39    }
40
41    /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred,
42    /// using the inner [`MicroSeconds`]’s [`checked_add()`](MicroSeconds::checked_add) method.
43    #[inline]
44    pub fn checked_add(self, rhs: MicroSeconds) -> Option<Self> {
45        self.0.checked_add(rhs).and_then(|us| Some(Self(us)))
46    }
47
48    /// Checked integer addition. Computes `self + rhs`, returning `None` if overflow occurred,
49    /// using the inner integer’s `checked_add()` method.
50    #[inline]
51    pub fn checked_add_duration(self, rhs: Duration) -> Option<Self> {
52        self.0.checked_add_duration(rhs).and_then(|i| Some(Self(i)))
53    }
54
55    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred,
56    /// using the inner [`MicroSeconds`]’s [`checked_sub()`](MicroSeconds::checked_sub) method.
57    #[inline]
58    pub fn checked_sub(self, rhs: MicroSeconds) -> Option<Self> {
59        self.0.checked_sub(rhs).and_then(|us| Some(Self(us)))
60    }
61
62    /// Checked integer subtraction. Computes `self - rhs`, returning `None` if overflow occurred,
63    /// using the inner integer’s `checked_sub()` method.
64    #[inline]
65    pub fn checked_sub_duration(self, rhs: Duration) -> Option<Self> {
66        self.0.checked_sub_duration(rhs).and_then(|i| Some(Self(i)))
67    }
68}
69
70impl std::fmt::Display for MonotonicTs {
71    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
72        write!(f, "{}", self.0)
73    }
74}
75
76impl Add<MicroSeconds> for MonotonicTs {
77    type Output = Self;
78
79    #[track_caller]
80    #[inline]
81    fn add(self, rhs: MicroSeconds) -> Self {
82        self.checked_add(rhs).expect(op_err::ADD)
83    }
84}
85impl AddAssign<MicroSeconds> for MonotonicTs {
86    #[track_caller]
87    #[inline]
88    fn add_assign(&mut self, rhs: MicroSeconds) {
89        *self = self.add(rhs);
90    }
91}
92
93impl Sub<MicroSeconds> for MonotonicTs {
94    type Output = Self;
95
96    #[track_caller]
97    #[inline]
98    fn sub(self, rhs: MicroSeconds) -> Self {
99        self.checked_sub(rhs).expect(op_err::SUB)
100    }
101}
102impl SubAssign<MicroSeconds> for MonotonicTs {
103    #[track_caller]
104    #[inline]
105    fn sub_assign(&mut self, rhs: MicroSeconds) {
106        *self = self.sub(rhs);
107    }
108}
109
110impl Add<Duration> for MonotonicTs {
111    type Output = Self;
112
113    #[track_caller]
114    #[inline]
115    fn add(self, rhs: Duration) -> Self {
116        Self(self.0.add(rhs))
117    }
118}
119impl AddAssign<Duration> for MonotonicTs {
120    #[track_caller]
121    #[inline]
122    fn add_assign(&mut self, rhs: Duration) {
123        *self = self.add(rhs);
124    }
125}
126
127impl Sub<Duration> for MonotonicTs {
128    type Output = Self;
129
130    #[track_caller]
131    #[inline]
132    fn sub(self, rhs: Duration) -> Self {
133        Self(self.0.sub(rhs))
134    }
135}
136impl SubAssign<Duration> for MonotonicTs {
137    #[track_caller]
138    #[inline]
139    fn sub_assign(&mut self, rhs: Duration) {
140        *self = self.sub(rhs);
141    }
142}