1#![allow(warnings)]
11
12use std::fmt;
15use std::time::Duration;
16
17use serde::de::{Error, MapAccess, SeqAccess, Visitor};
18use serde::{Deserialize, Deserializer, Serialize, Serializer};
19
20use super::SystemTime;
21
22impl<'de> Deserialize<'de> for SystemTime {
23 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
24 where
25 D: Deserializer<'de>,
26 {
27 enum Field {
29 Secs,
30 Nanos,
31 }
32
33 impl<'de> Deserialize<'de> for Field {
34 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
35 where
36 D: Deserializer<'de>,
37 {
38 struct FieldVisitor;
39
40 impl<'de> Visitor<'de> for FieldVisitor {
41 type Value = Field;
42
43 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44 formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
45 }
46
47 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
48 where
49 E: Error,
50 {
51 match value {
52 "secs_since_epoch" => Ok(Field::Secs),
53 "nanos_since_epoch" => Ok(Field::Nanos),
54 _ => Err(Error::unknown_field(value, FIELDS)),
55 }
56 }
57
58 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
59 where
60 E: Error,
61 {
62 match value {
63 b"secs_since_epoch" => Ok(Field::Secs),
64 b"nanos_since_epoch" => Ok(Field::Nanos),
65 _ => {
66 let value = String::from_utf8_lossy(value);
67 Err(Error::unknown_field(&value, FIELDS))
68 }
69 }
70 }
71 }
72
73 deserializer.deserialize_identifier(FieldVisitor)
74 }
75 }
76
77 fn check_overflow<E>(secs: u64, nanos: u32) -> Result<(), E>
78 where
79 E: Error,
80 {
81 static NANOS_PER_SEC: u32 = 1_000_000_000;
82 match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
83 Some(_) => Ok(()),
84 None => Err(E::custom("overflow deserializing SystemTime epoch offset")),
85 }
86 }
87
88 struct DurationVisitor;
89
90 impl<'de> Visitor<'de> for DurationVisitor {
91 type Value = Duration;
92
93 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
94 formatter.write_str("struct SystemTime")
95 }
96
97 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
98 where
99 A: SeqAccess<'de>,
100 {
101 let secs: u64 = match seq.next_element()? {
102 Some(value) => value,
103 None => {
104 return Err(Error::invalid_length(0, &self));
105 }
106 };
107 let nanos: u32 = match seq.next_element()? {
108 Some(value) => value,
109 None => {
110 return Err(Error::invalid_length(1, &self));
111 }
112 };
113 check_overflow(secs, nanos)?;
114 Ok(Duration::new(secs, nanos))
115 }
116
117 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
118 where
119 A: MapAccess<'de>,
120 {
121 let mut secs: Option<u64> = None;
122 let mut nanos: Option<u32> = None;
123 while let Some(key) = map.next_key()? {
124 match key {
125 Field::Secs => {
126 if secs.is_some() {
127 return Err(<A::Error as Error>::duplicate_field(
128 "secs_since_epoch",
129 ));
130 }
131 secs = Some(map.next_value()?);
132 }
133 Field::Nanos => {
134 if nanos.is_some() {
135 return Err(<A::Error as Error>::duplicate_field(
136 "nanos_since_epoch",
137 ));
138 }
139 nanos = Some(map.next_value()?);
140 }
141 }
142 }
143 let secs = match secs {
144 Some(secs) => secs,
145 None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
146 };
147 let nanos = match nanos {
148 Some(nanos) => nanos,
149 None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
150 };
151 check_overflow(secs, nanos)?;
152 Ok(Duration::new(secs, nanos))
153 }
154 }
155
156 const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"];
157 let duration = deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)?;
158 let ret = Ok(Self(duration));
160 ret
161 }
162}
163
164impl Serialize for SystemTime {
165 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
166 where
167 S: Serializer,
168 {
169 use serde::ser::SerializeStruct;
170 let duration_since_epoch = self.0;
172 let mut state = serializer.serialize_struct("SystemTime", 2)?;
173 state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs())?;
174 state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos())?;
175 state.end()
176 }
177}