Handle empty query params properly #90
1 changed files with 20 additions and 2 deletions
22
src/main.rs
22
src/main.rs
|
@ -414,6 +414,24 @@ fn main() -> Result<()> {
|
||||||
.wrap_err("failed to run main loop")
|
.wrap_err("failed to run main loop")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Serde deserialization decorator to map empty Strings to None,
|
||||||
|
///
|
||||||
|
/// Adapted from: <https://github.com/tokio-rs/axum/blob/main/examples/query-params-with-empty-strings/src/main.rs>
|
||||||
|
fn empty_string_as_none<'de, D, T>(de: D) -> Result<Option<T>, 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::<T>().map_err(serde::de::Error::custom).map(Some),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize)]
|
#[derive(Debug, serde::Deserialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
struct FritzBoxUpdateParams {
|
struct FritzBoxUpdateParams {
|
||||||
|
@ -422,10 +440,10 @@ struct FritzBoxUpdateParams {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
domain: Option<String>,
|
domain: Option<String>,
|
||||||
/// IPv4 address for the domain
|
/// IPv4 address for the domain
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
ipv4: Option<Ipv4Addr>,
|
ipv4: Option<Ipv4Addr>,
|
||||||
/// IPv6 address for the domain
|
/// IPv6 address for the domain
|
||||||
#[serde(default)]
|
#[serde(default, deserialize_with = "empty_string_as_none")]
|
||||||
ipv6: Option<Ipv6Addr>,
|
ipv6: Option<Ipv6Addr>,
|
||||||
/// IPv6 prefix for the home network
|
/// IPv6 prefix for the home network
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
Loading…
Add table
Reference in a new issue