1use std::{num::ParseIntError, str::FromStr, time::Duration};
2
3#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
14pub enum Timeout {
15 #[default]
19 Default,
20
21 Never,
23
24 Milliseconds(u32),
26}
27
28#[test]
29fn timeout_from_i32() {
30 assert_eq!(Timeout::from(234), Timeout::Milliseconds(234));
31 assert_eq!(Timeout::from(-234), Timeout::Default);
32 assert_eq!(Timeout::from(0), Timeout::Never);
33}
34
35impl From<i32> for Timeout {
36 fn from(int: i32) -> Timeout {
37 use std::cmp::Ordering::*;
38 match int.cmp(&0) {
39 Greater => Timeout::Milliseconds(int as u32),
40 Less => Timeout::Default,
41 Equal => Timeout::Never,
42 }
43 }
44}
45
46impl From<Duration> for Timeout {
47 fn from(duration: Duration) -> Timeout {
48 if duration.is_zero() {
49 Timeout::Never
50 } else if duration.as_millis() > u32::MAX as u128 {
51 Timeout::Default
52 } else {
53 Timeout::Milliseconds(duration.as_millis().try_into().unwrap_or(u32::MAX))
54 }
55 }
56}
57
58impl From<Timeout> for i32 {
59 fn from(timeout: Timeout) -> Self {
60 match timeout {
61 Timeout::Default => -1,
62 Timeout::Never => 0,
63 Timeout::Milliseconds(ms) => ms as i32,
64 }
65 }
66}
67
68impl FromStr for Timeout {
69 type Err = ParseIntError;
70
71 fn from_str(s: &str) -> Result<Self, Self::Err> {
72 match s {
73 "default" => Ok(Timeout::Default),
74 "never" => Ok(Timeout::Never),
75 milliseconds => Ok(Timeout::Milliseconds(u32::from_str(milliseconds)?)),
76 }
77 }
78}
79
80pub struct TimeoutMessage(Timeout);
81
82impl From<Timeout> for TimeoutMessage {
83 fn from(hint: Timeout) -> Self {
84 TimeoutMessage(hint)
85 }
86}
87
88impl std::ops::Deref for TimeoutMessage {
89 type Target = Timeout;
90
91 fn deref(&self) -> &Self::Target {
92 &self.0
93 }
94}
95
96#[cfg(all(feature = "dbus", unix, not(target_os = "macos")))]
97impl TryFrom<&dbus::arg::messageitem::MessageItem> for TimeoutMessage {
98 type Error = ();
99
100 fn try_from(mi: &dbus::arg::messageitem::MessageItem) -> Result<TimeoutMessage, ()> {
101 mi.inner::<i32>().map(|i| TimeoutMessage(i.into()))
102 }
103}