From 2ee66e812f9be58946081e96c1f058330476c4aa Mon Sep 17 00:00:00 2001 From: Imbolc Date: Tue, 9 Nov 2021 15:05:31 +0300 Subject: [PATCH] `FromStr` based `empty_string_as_none` implementation (#486) --- .../src/main.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/query-params-with-empty-strings/src/main.rs b/examples/query-params-with-empty-strings/src/main.rs index 0b22f29c..aa424643 100644 --- a/examples/query-params-with-empty-strings/src/main.rs +++ b/examples/query-params-with-empty-strings/src/main.rs @@ -5,7 +5,8 @@ //! ``` use axum::{extract::Query, routing::get, Router}; -use serde::{de::IntoDeserializer, Deserialize, Deserializer}; +use serde::{de, Deserialize, Deserializer}; +use std::{fmt, str::FromStr}; #[tokio::main] async fn main() { @@ -34,7 +35,7 @@ async fn handler(Query(params): Query) -> String { #[allow(dead_code)] struct Params { #[serde(default, deserialize_with = "empty_string_as_none")] - foo: Option, + foo: Option, bar: Option, } @@ -42,12 +43,13 @@ struct Params { fn empty_string_as_none<'de, D, T>(de: D) -> Result, D::Error> where D: Deserializer<'de>, - T: Deserialize<'de>, + T: FromStr, + T::Err: fmt::Display, { let opt = Option::::deserialize(de)?; match opt.as_deref() { None | Some("") => Ok(None), - Some(s) => T::deserialize(s.into_deserializer()).map(Some), + Some(s) => FromStr::from_str(s).map_err(de::Error::custom).map(Some), } } @@ -60,8 +62,8 @@ mod tests { #[tokio::test] async fn test_something() { assert_eq!( - send_request_get_body("foo=foo&bar=bar").await, - r#"Params { foo: Some("foo"), bar: Some("bar") }"#, + send_request_get_body("foo=1&bar=bar").await, + r#"Params { foo: Some(1), bar: Some("bar") }"#, ); assert_eq!( @@ -75,8 +77,8 @@ mod tests { ); assert_eq!( - send_request_get_body("foo=foo").await, - r#"Params { foo: Some("foo"), bar: None }"#, + send_request_get_body("foo=1").await, + r#"Params { foo: Some(1), bar: None }"#, ); assert_eq!(