diff options
Diffstat (limited to 'src/config.rs')
-rw-r--r-- | src/config.rs | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/src/config.rs b/src/config.rs index 76f65db..c6306bc 100644 --- a/src/config.rs +++ b/src/config.rs @@ -37,6 +37,10 @@ fn default_id() -> String { PROGRAM.to_string() } +fn default_timeout() -> Duration { + Duration::from_secs(60) +} + #[allow(clippy::enum_variant_names)] #[derive(Deserialize, Debug)] #[serde(remote = "QoS", rename_all = "kebab-case")] @@ -116,6 +120,57 @@ impl<'de> Deserialize<'de> for Route { } } +pub fn deserialize_timeout<'de, D>(deserializer: D) -> Result<Duration, D::Error> +where + D: Deserializer<'de>, +{ + struct DurationVisitor; + + impl<'de> de::Visitor<'de> for DurationVisitor { + type Value = Duration; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a positive number") + } + + fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E> + where + E: de::Error, + { + if v < 0 { + return Err(de::Error::invalid_value( + de::Unexpected::Signed(v), + &"a non-negative number", + )); + } + if v == 0 { + Ok(Duration::MAX) + } else { + Ok(Duration::from_secs(v as u64)) + } + } + + fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E> + where + E: de::Error, + { + if v < 0.0 { + return Err(de::Error::invalid_value( + de::Unexpected::Float(v), + &"a non-negative number", + )); + } + if v == 0.0 { + Ok(Duration::MAX) + } else { + Ok(Duration::from_secs_f64(v)) + } + } + } + + deserializer.deserialize_any(DurationVisitor) +} + #[derive(Deserialize, Debug)] pub struct Config { #[serde(default = "default_host")] @@ -124,6 +179,8 @@ pub struct Config { pub port: u16, #[serde(with = "QoSDef", default = "default_qos")] pub qos: QoS, + #[serde(default = "default_timeout", deserialize_with = "deserialize_timeout")] + pub timeout: Duration, pub credentials: Option<Credentials>, #[serde(default = "default_id")] pub id: String, |