hocon_linked/serde/
wrappers.rs1use std::{
4 fmt,
5 ops::{Deref, DerefMut},
6 time::Duration,
7};
8
9use serde::{
10 de::{self, Deserialize, Visitor},
11 Deserializer,
12};
13
14use crate::Hocon;
15
16#[doc(alias = "Duration")]
57#[derive(Debug)]
58pub struct Serde<T>(T);
59
60impl<T> Deref for Serde<T> {
61 type Target = T;
62
63 fn deref(&self) -> &Self::Target {
64 &self.0
65 }
66}
67
68impl<T> DerefMut for Serde<T> {
69 fn deref_mut(&mut self) -> &mut Self::Target {
70 &mut self.0
71 }
72}
73
74struct StringDurationVisitor;
75
76impl<'de> Visitor<'de> for StringDurationVisitor {
77 type Value = Duration;
78
79 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
80 formatter.write_str("a duration")
81 }
82
83 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
84 where
85 E: de::Error,
86 {
87 let duration = Hocon::str_as_milliseconds(&v)
88 .ok_or_else(|| E::custom(format!("expected duration, found \"{}\"", v)))?;
89
90 Ok(Duration::from_secs_f64(duration / 1000.0))
91 }
92
93 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
94 where
95 E: de::Error,
96 {
97 let duration = Hocon::str_as_milliseconds(v)
98 .ok_or_else(|| E::custom(format!("expected duration, found \"{}\"", v)))?;
99
100 Ok(Duration::from_secs_f64(duration / 1000.0))
101 }
102}
103
104impl<'de> Deserialize<'de> for Serde<Duration> {
105 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
106 where
107 D: Deserializer<'de>,
108 {
109 Ok(Serde(deserializer.deserialize_str(StringDurationVisitor)?))
110 }
111}
112
113impl Serde<Duration> {
114 pub fn with<'de, D>(deserializer: D) -> Result<Duration, D::Error>
116 where
117 D: Deserializer<'de>,
118 {
119 deserializer.deserialize_str(StringDurationVisitor)
120 }
121}