web_time/time/
serde.rs

1//! Serde serialization and de-serialization for `SystemTime`. It aims to be
2//! compatible with Serde's implementation for [`std::time::SystemTime`].
3//!
4//! This implementation was copied from Serde's
5//! [`Deserialize`](https://github.com/serde-rs/serde/blob/5fa711d75d91173aafc6019e03cf8af6ac9ba7b2/serde/src/de/impls.rs#L2168-L2314),
6//! and
7//! [`Sserialize`](https://github.com/serde-rs/serde/blob/5fa711d75d91173aafc6019e03cf8af6ac9ba7b2/serde/src/ser/impls.rs#L730-L747)
8//! implementation.
9
10#![allow(warnings)]
11
12// CHANGED: Replaced occurrences of `tri!` macro with `?`.
13
14use 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		// Reuse duration
28		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		// CHANGED: Insert `Duration` directly.
159		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		// CHANGED: Take `Duration` directly.
171		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}