From 82012066e86a53c4456e0e069378fb3babe2adf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jalil=20David=20Salam=C3=A9=20Messina?= Date: Fri, 31 Jan 2025 21:04:36 +0100 Subject: [PATCH] fix(webnsupdate): make IP none when query is empty This happens when one of the IPs hasn't changed (but the other has) in the FRITZ!Box DDNS client. --- src/main.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/main.rs b/src/main.rs index d522390..035b4ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -414,6 +414,24 @@ fn main() -> Result<()> { .wrap_err("failed to run main loop") } +/// Serde deserialization decorator to map empty Strings to None, +/// +/// Adapted from: +fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, + T: std::str::FromStr, + T::Err: std::fmt::Display, +{ + use serde::Deserialize; + + let opt = Option::<&'de str>::deserialize(de)?; + match opt { + None | Some("") => Ok(None), + Some(s) => s.parse::().map_err(serde::de::Error::custom).map(Some), + } +} + #[derive(Debug, serde::Deserialize)] #[serde(deny_unknown_fields)] struct FritzBoxUpdateParams { @@ -422,10 +440,10 @@ struct FritzBoxUpdateParams { #[serde(default)] domain: Option, /// IPv4 address for the domain - #[serde(default)] + #[serde(default, deserialize_with = "empty_string_as_none")] ipv4: Option, /// IPv6 address for the domain - #[serde(default)] + #[serde(default, deserialize_with = "empty_string_as_none")] ipv6: Option, /// IPv6 prefix for the home network #[allow(unused)]