nix/
poll_timeout.rs

1use std::time::Duration;
2
3/// PollTimeout argument for polling.
4#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)]
5pub struct PollTimeout(i32);
6
7impl PollTimeout {
8    /// Blocks indefinitely.
9    ///
10    /// > Specifying a negative value in timeout means an infinite timeout.
11    pub const NONE: Self = Self(-1);
12    /// Returns immediately.
13    ///
14    /// > Specifying a timeout of zero causes poll() to return immediately, even if no file
15    /// > descriptors are ready.
16    pub const ZERO: Self = Self(0);
17    /// Blocks for at most [`i32::MAX`] milliseconds.
18    pub const MAX: Self = Self(i32::MAX);
19    /// Returns if `self` equals [`PollTimeout::NONE`].
20    pub fn is_none(&self) -> bool {
21        // > Specifying a negative value in timeout means an infinite timeout.
22        *self <= Self::NONE
23    }
24    /// Returns if `self` does not equal [`PollTimeout::NONE`].
25    pub fn is_some(&self) -> bool {
26        !self.is_none()
27    }
28    /// Returns the timeout in milliseconds if there is some, otherwise returns `None`.
29    pub fn as_millis(&self) -> Option<u32> {
30        self.is_some().then_some(u32::try_from(self.0).unwrap())
31    }
32    /// Returns the timeout as a `Duration` if there is some, otherwise returns `None`.
33    pub fn duration(&self) -> Option<Duration> {
34        self.as_millis()
35            .map(|x| Duration::from_millis(u64::from(x)))
36    }
37}
38
39/// Error type for integer conversions into `PollTimeout`.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum PollTimeoutTryFromError {
42    /// Passing a value less than -1 is invalid on some systems, see
43    /// <https://man.freebsd.org/cgi/man.cgi?poll#end>.
44    TooNegative,
45    /// Passing a value greater than `i32::MAX` is invalid.
46    TooPositive,
47}
48
49impl std::fmt::Display for PollTimeoutTryFromError {
50    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51        match self {
52            Self::TooNegative => write!(f, "Passed a negative timeout less than -1."),
53            Self::TooPositive => write!(f, "Passed a positive timeout greater than `i32::MAX` milliseconds.")
54        }
55    }
56}
57
58impl std::error::Error for PollTimeoutTryFromError {}
59
60impl<T: Into<PollTimeout>> From<Option<T>> for PollTimeout {
61    fn from(x: Option<T>) -> Self {
62        x.map_or(Self::NONE, |x| x.into())
63    }
64}
65impl TryFrom<Duration> for PollTimeout {
66    type Error = PollTimeoutTryFromError;
67    fn try_from(x: Duration) -> std::result::Result<Self, Self::Error> {
68        Ok(Self(
69            i32::try_from(x.as_millis())
70                .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
71        ))
72    }
73}
74impl TryFrom<u128> for PollTimeout {
75    type Error = PollTimeoutTryFromError;
76    fn try_from(x: u128) -> std::result::Result<Self, Self::Error> {
77        Ok(Self(
78            i32::try_from(x)
79                .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
80        ))
81    }
82}
83impl TryFrom<u64> for PollTimeout {
84    type Error = PollTimeoutTryFromError;
85    fn try_from(x: u64) -> std::result::Result<Self, Self::Error> {
86        Ok(Self(
87            i32::try_from(x)
88                .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
89        ))
90    }
91}
92impl TryFrom<u32> for PollTimeout {
93    type Error = PollTimeoutTryFromError;
94    fn try_from(x: u32) -> std::result::Result<Self, Self::Error> {
95        Ok(Self(
96            i32::try_from(x)
97                .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
98        ))
99    }
100}
101impl From<u16> for PollTimeout {
102    fn from(x: u16) -> Self {
103        Self(i32::from(x))
104    }
105}
106impl From<u8> for PollTimeout {
107    fn from(x: u8) -> Self {
108        Self(i32::from(x))
109    }
110}
111impl TryFrom<i128> for PollTimeout {
112    type Error = PollTimeoutTryFromError;
113    fn try_from(x: i128) -> std::result::Result<Self, Self::Error> {
114        match x {
115            ..=-2 => Err(PollTimeoutTryFromError::TooNegative),
116            -1.. => Ok(Self(
117                i32::try_from(x)
118                    .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
119            )),
120        }
121    }
122}
123impl TryFrom<i64> for PollTimeout {
124    type Error = PollTimeoutTryFromError;
125    fn try_from(x: i64) -> std::result::Result<Self, Self::Error> {
126        match x {
127            ..=-2 => Err(PollTimeoutTryFromError::TooNegative),
128            -1.. => Ok(Self(
129                i32::try_from(x)
130                    .map_err(|_| PollTimeoutTryFromError::TooPositive)?,
131            )),
132        }
133    }
134}
135impl TryFrom<i32> for PollTimeout {
136    type Error = PollTimeoutTryFromError;
137    fn try_from(x: i32) -> std::result::Result<Self, Self::Error> {
138        match x {
139            ..=-2 => Err(PollTimeoutTryFromError::TooNegative),
140            -1.. => Ok(Self(x)),
141        }
142    }
143}
144impl TryFrom<i16> for PollTimeout {
145    type Error = PollTimeoutTryFromError;
146    fn try_from(x: i16) -> std::result::Result<Self, Self::Error> {
147        match x {
148            ..=-2 => Err(PollTimeoutTryFromError::TooNegative),
149            -1.. => Ok(Self(i32::from(x))),
150        }
151    }
152}
153impl TryFrom<i8> for PollTimeout {
154    type Error = PollTimeoutTryFromError;
155    fn try_from(x: i8) -> std::result::Result<Self, Self::Error> {
156        match x {
157            ..=-2 => Err(PollTimeoutTryFromError::TooNegative),
158            -1.. => Ok(Self(i32::from(x))),
159        }
160    }
161}
162impl TryFrom<PollTimeout> for Duration {
163    type Error = ();
164    fn try_from(x: PollTimeout) -> std::result::Result<Self, ()> {
165        x.duration().ok_or(())
166    }
167}
168impl TryFrom<PollTimeout> for u128 {
169    type Error = <Self as TryFrom<i32>>::Error;
170    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
171        Self::try_from(x.0)
172    }
173}
174impl TryFrom<PollTimeout> for u64 {
175    type Error = <Self as TryFrom<i32>>::Error;
176    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
177        Self::try_from(x.0)
178    }
179}
180impl TryFrom<PollTimeout> for u32 {
181    type Error = <Self as TryFrom<i32>>::Error;
182    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
183        Self::try_from(x.0)
184    }
185}
186impl TryFrom<PollTimeout> for u16 {
187    type Error = <Self as TryFrom<i32>>::Error;
188    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
189        Self::try_from(x.0)
190    }
191}
192impl TryFrom<PollTimeout> for u8 {
193    type Error = <Self as TryFrom<i32>>::Error;
194    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
195        Self::try_from(x.0)
196    }
197}
198impl From<PollTimeout> for i128 {
199    fn from(x: PollTimeout) -> Self {
200        Self::from(x.0)
201    }
202}
203impl From<PollTimeout> for i64 {
204    fn from(x: PollTimeout) -> Self {
205        Self::from(x.0)
206    }
207}
208impl From<PollTimeout> for i32 {
209    fn from(x: PollTimeout) -> Self {
210        x.0
211    }
212}
213impl TryFrom<PollTimeout> for i16 {
214    type Error = <Self as TryFrom<i32>>::Error;
215    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
216        Self::try_from(x.0)
217    }
218}
219impl TryFrom<PollTimeout> for i8 {
220    type Error = <Self as TryFrom<i32>>::Error;
221    fn try_from(x: PollTimeout) -> std::result::Result<Self, Self::Error> {
222        Self::try_from(x.0)
223    }
224}