proto_types/duration/
duration_impls.rs1use crate::Duration;
2
3impl core::cmp::PartialOrd for Duration {
4 #[inline]
5 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
6 Some(self.cmp(other))
7 }
8}
9
10impl core::cmp::Ord for Duration {
11 #[inline]
12 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
13 self.total_nanos().cmp(&other.total_nanos())
14 }
15}
16
17#[cfg(feature = "serde")]
18mod serde {
19 use core::fmt;
20
21 use serde::{Deserialize, Deserializer, Serialize, Serializer, de};
22
23 use crate::{Duration, ToString, format};
24
25 impl Serialize for Duration {
26 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27 where
28 S: Serializer,
29 {
30 let self_normalized = self.normalized();
31
32 let seconds = self_normalized.seconds;
33 let nanos = self_normalized.nanos;
34
35 let formatted_string = if nanos == 0 {
36 format!("{seconds}s")
38 } else {
39 let fractional_seconds_str = format!("{nanos:09}");
40
41 let trimmed_fractional_seconds = fractional_seconds_str.trim_end_matches('0');
42
43 format!("{seconds}.{trimmed_fractional_seconds}s")
44 };
45
46 serializer.serialize_str(&formatted_string)
47 }
48 }
49
50 impl<'de> Deserialize<'de> for Duration {
51 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
52 where
53 D: Deserializer<'de>,
54 {
55 struct DurationVisitor;
56
57 impl de::Visitor<'_> for DurationVisitor {
58 type Value = Duration;
59
60 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
61 formatter.write_str("A duration ending in 's'")
62 }
63
64 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
65 where
66 E: de::Error,
67 {
68 if !value.ends_with('s') {
69 return Err(de::Error::custom("Duration should end with 's'"));
70 }
71
72 let duration_str = &value[..value.len() - 1]; let mut parts = duration_str.split('.'); let seconds: i64 = parts
77 .next()
78 .ok_or_else(|| de::Error::custom("Missing seconds"))?
79 .parse()
80 .map_err(de::Error::custom)?;
81
82 let nanos: i32 = match parts.next() {
83 Some(fraction) => {
84 let mut fraction_str = fraction.to_string(); if fraction_str.len() > 9 {
87 return Err(de::Error::custom(format!(
89 "Fractional part has more than 9 digits: {}",
90 fraction_str.len()
91 )));
92 }
93 fraction_str.reserve(9 - fraction_str.len()); for _ in fraction_str.len()..9 {
95 fraction_str.push('0');
96 }
97
98 fraction_str.parse().map_err(de::Error::custom)?
99 }
100 None => 0,
101 };
102
103 let mut duration = Duration { seconds, nanos };
104 duration.normalize(); Ok(duration)
107 }
108 }
109
110 deserializer.deserialize_str(DurationVisitor)
111 }
112 }
113}