1use std::fmt;
2
3use serde::{
4 de::{self, Unexpected, Visitor},
5 ser::{Serialize, Serializer},
6 Deserialize, Deserializer,
7};
8
9#[derive(Debug, PartialEq, Eq, Clone, Copy)]
14#[allow(missing_docs)]
15pub enum Time {
16 Days(u64),
17 Hours(u64),
18 Minutes(u64),
19 Seconds(u64),
20 Milliseconds(u64),
21 Microseconds(u64),
22 Nanoseconds(u64),
23}
24
25impl Serialize for Time {
26 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
27 where
28 S: Serializer,
29 {
30 match self {
31 Self::Days(u) => format!("{u}d"),
32 Self::Hours(u) => format!("{u}h"),
33 Self::Minutes(u) => format!("{u}m"),
34 Self::Seconds(u) => format!("{u}s"),
35 Self::Milliseconds(u) => format!("{u}ms"),
36 Self::Microseconds(u) => format!("{u}micros"),
37 Self::Nanoseconds(u) => format!("{u}nanos"),
38 }
39 .serialize(serializer)
40 }
41}
42
43impl<'de> Deserialize<'de> for Time {
44 fn deserialize<D>(deserializer: D) -> Result<Time, D::Error>
45 where
46 D: Deserializer<'de>,
47 {
48 struct TimeVisitor;
49
50 impl<'de> Visitor<'de> for TimeVisitor {
51 type Value = Time;
52
53 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
54 formatter.write_str("a string representing a duration")
55 }
56
57 fn visit_str<E>(self, value: &str) -> Result<Time, E>
58 where
59 E: de::Error,
60 {
61 let len = value.len();
62 let number = &value[..len - 1];
63 let unit = &value[len - 1..];
64
65 let number = number.parse::<u64>().map_err(E::custom)?;
66
67 match unit {
68 "d" => Ok(Time::Days(number)),
69 "h" => Ok(Time::Hours(number)),
70 "m" => Ok(Time::Minutes(number)),
71 "s" => Ok(Time::Seconds(number)),
72 "ms" => Ok(Time::Milliseconds(number)),
73 "micros" => Ok(Time::Microseconds(number)),
74 "nanos" => Ok(Time::Nanoseconds(number)),
75 _ => Err(E::custom(format!("unknown time unit: {}", unit))),
76 }
77 }
78 }
79
80 deserializer.deserialize_str(TimeVisitor)
81 }
82}
83#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Deserialize, Serialize)]
90#[serde(rename_all = "snake_case")]
91pub enum CalendarInterval {
92 Minute,
98 Hour,
104 Day,
109 Week,
113 Month,
118 Quarter,
123 Year,
128}
129
130#[derive(Debug, PartialEq, Eq, Clone, Copy)]
137#[allow(missing_docs)]
138pub enum Byte {
139 Bytes(u64),
140 Kilobytes(u64),
141 Megabytes(u64),
142 Gigabytes(u64),
143 Terabytes(u64),
144 Petabytes(u64),
145}
146
147impl Serialize for Byte {
148 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
149 where
150 S: Serializer,
151 {
152 match self {
153 Self::Bytes(u) => format!("{u}b"),
154 Self::Kilobytes(u) => format!("{u}kb"),
155 Self::Megabytes(u) => format!("{u}mb"),
156 Self::Gigabytes(u) => format!("{u}gb"),
157 Self::Terabytes(u) => format!("{u}tb"),
158 Self::Petabytes(u) => format!("{u}pb"),
159 }
160 .serialize(serializer)
161 }
162}
163
164impl<'de> Deserialize<'de> for Byte {
165 fn deserialize<D>(deserializer: D) -> Result<Byte, D::Error>
166 where
167 D: Deserializer<'de>,
168 {
169 struct ByteVisitor;
170
171 impl<'de> Visitor<'de> for ByteVisitor {
172 type Value = Byte;
173
174 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
175 formatter.write_str("a string representing a byte size")
176 }
177
178 fn visit_str<E>(self, value: &str) -> Result<Byte, E>
179 where
180 E: de::Error,
181 {
182 let len = value.len();
183 let number = &value[..len - 2];
184 let unit = &value[len - 2..];
185
186 let number = number.parse::<u64>().map_err(E::custom)?;
187
188 match unit {
189 "b" => Ok(Byte::Bytes(number)),
190 "kb" => Ok(Byte::Kilobytes(number)),
191 "mb" => Ok(Byte::Megabytes(number)),
192 "gb" => Ok(Byte::Gigabytes(number)),
193 "tb" => Ok(Byte::Terabytes(number)),
194 "pb" => Ok(Byte::Petabytes(number)),
195 _ => Err(E::custom(format!("unknown byte unit: {}", unit))),
196 }
197 }
198 }
199
200 deserializer.deserialize_str(ByteVisitor)
201 }
202}
203
204#[derive(Debug, PartialEq, Eq, Clone, Copy)]
212#[allow(missing_docs)]
213pub enum Size {
214 Kilo(u64),
215 Mega(u64),
216 Giga(u64),
217 Tera(u64),
218 Peta(u64),
219}
220
221impl Serialize for Size {
222 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
223 where
224 S: Serializer,
225 {
226 match self {
227 Self::Kilo(u) => format!("{u}k"),
228 Self::Mega(u) => format!("{u}m"),
229 Self::Giga(u) => format!("{u}g"),
230 Self::Tera(u) => format!("{u}t"),
231 Self::Peta(u) => format!("{u}p"),
232 }
233 .serialize(serializer)
234 }
235}
236
237impl<'de> Deserialize<'de> for Size {
238 fn deserialize<D>(deserializer: D) -> Result<Size, D::Error>
239 where
240 D: Deserializer<'de>,
241 {
242 struct SizeVisitor;
243
244 impl<'de> Visitor<'de> for SizeVisitor {
245 type Value = Size;
246
247 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
248 formatter.write_str("a string representing a size")
249 }
250
251 fn visit_str<E>(self, value: &str) -> Result<Size, E>
252 where
253 E: de::Error,
254 {
255 let len = value.len();
256 let number = &value[..len - 1];
257 let unit = &value[len - 1..];
258
259 let number = number.parse::<u64>().map_err(E::custom)?;
260
261 match unit {
262 "k" => Ok(Size::Kilo(number)),
263 "m" => Ok(Size::Mega(number)),
264 "g" => Ok(Size::Giga(number)),
265 "t" => Ok(Size::Tera(number)),
266 "p" => Ok(Size::Peta(number)),
267 _ => Err(E::custom(format!("unknown size unit: {}", unit))),
268 }
269 }
270 }
271
272 deserializer.deserialize_str(SizeVisitor)
273 }
274}
275
276#[derive(Debug, PartialEq, Eq, Clone, Copy)]
285#[allow(missing_docs)]
286pub enum Distance {
287 Miles(u64),
288 Yards(u64),
289 Feet(u64),
290 Inches(u64),
291 Kilometers(u64),
292 Meters(u64),
293 Centimeter(u64),
294 Millimeters(u64),
295 NauticalMiles(u64),
296}
297
298impl Default for Distance {
299 fn default() -> Self {
300 Self::Meters(100)
301 }
302}
303
304impl Serialize for Distance {
305 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
306 where
307 S: Serializer,
308 {
309 match self {
310 Self::Miles(u) => format!("{u}mi"),
311 Self::Yards(u) => format!("{u}yd"),
312 Self::Feet(u) => format!("{u}ft"),
313 Self::Inches(u) => format!("{u}in"),
314 Self::Kilometers(u) => format!("{u}km"),
315 Self::Meters(u) => format!("{u}m"),
316 Self::Centimeter(u) => format!("{u}cm"),
317 Self::Millimeters(u) => format!("{u}mm"),
318 Self::NauticalMiles(u) => format!("{u}nmi"),
319 }
320 .serialize(serializer)
321 }
322}
323
324impl<'de> Deserialize<'de> for Distance {
325 fn deserialize<D>(deserializer: D) -> Result<Distance, D::Error>
326 where
327 D: Deserializer<'de>,
328 {
329 struct DistanceVisitor;
330
331 impl<'de> Visitor<'de> for DistanceVisitor {
332 type Value = Distance;
333
334 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
335 formatter.write_str("a string representing a distance")
336 }
337
338 fn visit_str<E>(self, value: &str) -> Result<Distance, E>
339 where
340 E: de::Error,
341 {
342 let len = value.len();
343 let number = &value[..len - 2];
344 let unit = &value[len - 2..];
345
346 let number = number.parse::<u64>().map_err(E::custom)?;
347
348 match unit {
349 "mi" => Ok(Distance::Miles(number)),
350 "yd" => Ok(Distance::Yards(number)),
351 "ft" => Ok(Distance::Feet(number)),
352 "in" => Ok(Distance::Inches(number)),
353 "km" => Ok(Distance::Kilometers(number)),
354 "m" => Ok(Distance::Meters(number)),
355 "cm" => Ok(Distance::Centimeter(number)),
356 "mm" => Ok(Distance::Millimeters(number)),
357 "nmi" => Ok(Distance::NauticalMiles(number)),
358 _ => Err(E::custom(format!("unknown distance unit: {}", unit))),
359 }
360 }
361 }
362
363 deserializer.deserialize_str(DistanceVisitor)
364 }
365}
366
367#[derive(Debug, PartialEq, Eq, Clone, Copy)]
376#[allow(missing_docs)]
377pub enum DistanceUnit {
378 Miles,
379 Yards,
380 Feet,
381 Inches,
382 Kilometers,
383 Meters,
384 Centimeter,
385 Millimeters,
386 NauticalMiles,
387}
388
389impl Serialize for DistanceUnit {
390 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
391 where
392 S: Serializer,
393 {
394 match self {
395 Self::Miles => "mi",
396 Self::Yards => "yd",
397 Self::Feet => "ft",
398 Self::Inches => "in",
399 Self::Kilometers => "km",
400 Self::Meters => "m",
401 Self::Centimeter => "cm",
402 Self::Millimeters => "mm",
403 Self::NauticalMiles => "nmi",
404 }
405 .serialize(serializer)
406 }
407}
408
409impl<'de> Deserialize<'de> for DistanceUnit {
410 fn deserialize<D>(deserializer: D) -> Result<DistanceUnit, D::Error>
411 where
412 D: Deserializer<'de>,
413 {
414 struct DistanceUnitVisitor;
415
416 impl<'de> Visitor<'de> for DistanceUnitVisitor {
417 type Value = DistanceUnit;
418
419 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
420 formatter.write_str("a string representing a distance unit")
421 }
422
423 fn visit_str<E>(self, value: &str) -> Result<DistanceUnit, E>
424 where
425 E: de::Error,
426 {
427 match value {
428 "mi" => Ok(DistanceUnit::Miles),
429 "yd" => Ok(DistanceUnit::Yards),
430 "ft" => Ok(DistanceUnit::Feet),
431 "in" => Ok(DistanceUnit::Inches),
432 "km" => Ok(DistanceUnit::Kilometers),
433 "m" => Ok(DistanceUnit::Meters),
434 "cm" => Ok(DistanceUnit::Centimeter),
435 "mm" => Ok(DistanceUnit::Millimeters),
436 "nmi" => Ok(DistanceUnit::NauticalMiles),
437 _ => Err(E::invalid_value(Unexpected::Str(value), &self)),
438 }
439 }
440 }
441
442 deserializer.deserialize_str(DistanceUnitVisitor)
443 }
444}