input_linux/
time.rs

1use std::{fmt, cmp};
2use std::hash::{Hash, Hasher};
3use std::ops::{Deref, DerefMut};
4use crate::sys::timeval;
5use nix::libc::{time_t, suseconds_t};
6#[cfg(feature = "serde")]
7use serde::{Serialize, Deserialize};
8
9/// An event timestamp.
10#[repr(C)]
11#[derive(Copy, Clone)]
12#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
13pub struct EventTime(
14#[cfg_attr(feature = "serde", serde(with = "TimevalDef"))]
15timeval
16);
17
18#[cfg(feature = "serde")]
19#[derive(Serialize, Deserialize)]
20#[serde(remote = "timeval")]
21#[allow(dead_code)]
22struct TimevalDef {
23    tv_sec: time_t,
24    tv_usec: suseconds_t,
25}
26
27impl EventTime {
28    /// Create a new timestamp.
29    pub const fn new(secs: i64, usecs: i64) -> Self {
30        EventTime(timeval {
31            tv_sec: secs as time_t,
32            tv_usec: usecs as suseconds_t,
33        })
34    }
35
36    /// Create a timestamp given a libc [`timeval`].
37    pub const fn from_timeval(time: timeval) -> Self {
38        EventTime(time)
39    }
40
41    /// The timestamp represented as seconds since an epoch.
42    pub const fn seconds(&self) -> i64 {
43        (self.0).tv_sec as i64
44    }
45
46    /// Set the seconds component of the timestamp.
47    pub fn set_seconds(&mut self, value: i64) {
48        (self.0).tv_sec = value as time_t
49    }
50
51    /// The microseconds component of the seconds.
52    ///
53    /// This is meant to be modulo one second, though any value is technically
54    /// valid.
55    pub const fn microseconds(&self) -> i64 {
56        (self.0).tv_usec as i64
57    }
58
59    /// Set the microseconds component of the timestamp.
60    pub fn set_microseconds(&mut self, value: i64) {
61        (self.0).tv_usec = value as suseconds_t
62    }
63
64    /// The inner `libc` [`timeval`].
65    pub const fn into_inner(self) -> timeval {
66        self.0
67    }
68}
69
70impl Default for EventTime {
71    fn default() -> Self {
72        Self::new(0, 0)
73    }
74}
75
76impl fmt::Debug for EventTime {
77    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
78        f.debug_struct("EventTime")
79            .field("seconds", &(self.0).tv_sec)
80            .field("microseconds", &(self.0).tv_usec)
81            .finish()
82    }
83}
84
85impl From<timeval> for EventTime {
86    fn from(time: timeval) -> Self {
87        EventTime::from_timeval(time)
88    }
89}
90
91impl From<EventTime> for timeval {
92    fn from(time: EventTime) -> Self {
93        time.into_inner()
94    }
95}
96
97impl Deref for EventTime {
98    type Target = timeval;
99
100    fn deref(&self) -> &Self::Target {
101        &self.0
102    }
103}
104
105impl DerefMut for EventTime {
106    fn deref_mut(&mut self) -> &mut Self::Target {
107        &mut self.0
108    }
109}
110
111impl AsRef<timeval> for EventTime {
112    fn as_ref(&self) -> &timeval {
113        &self.0
114    }
115}
116
117impl<'a> From<&'a timeval> for &'a EventTime {
118    fn from(time: &'a timeval) -> Self {
119        unsafe {
120            let raw = time as *const _ as *const _;
121            &*raw
122        }
123    }
124}
125
126impl<'a> From<&'a mut timeval> for &'a mut EventTime {
127    fn from(time: &'a mut timeval) -> Self {
128        unsafe {
129            let raw = time as *mut _ as *mut _;
130            &mut *raw
131        }
132    }
133}
134
135impl PartialOrd for EventTime {
136    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
137        Some(self.cmp(other))
138    }
139}
140
141impl PartialEq for EventTime {
142    fn eq(&self, other: &Self) -> bool {
143        (self.0).tv_sec == (other.0).tv_sec &&
144            (self.0).tv_usec == (other.0).tv_usec
145    }
146}
147
148impl Hash for EventTime {
149    fn hash<H: Hasher>(&self, state: &mut H) {
150        (self.0).tv_sec.hash(state);
151        (self.0).tv_usec.hash(state);
152    }
153}
154
155impl Ord for EventTime {
156    fn cmp(&self, other: &Self) -> cmp::Ordering {
157        (self.0).tv_sec.cmp(&(other.0).tv_sec)
158            .then((self.0).tv_usec.cmp(&(other.0).tv_usec))
159    }
160}
161
162impl Eq for EventTime {}