From 48e0eb979fc7dcc5e7027fa89b61e17a634e897b Mon Sep 17 00:00:00 2001
From: fermeise <ocker.christian@gmail.com>
Date: Wed, 31 Jul 2019 12:55:48 +0200
Subject: Add deserialization parameters to QsQueryConfig

This allows switching to non-strict parsing mode

resolves #21
---
 src/actix.rs        | 36 +++++++++++++++++++++++++++++-------
 tests/test_actix.rs | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+), 7 deletions(-)

diff --git a/src/actix.rs b/src/actix.rs
index fdab33f..fa7e105 100644
--- a/src/actix.rs
+++ b/src/actix.rs
@@ -3,7 +3,10 @@
 //! Enable with the `actix` feature.
 
 use actix_web::dev::Payload;
-use actix_web::{Error as ActixError, FromRequest, HttpRequest, HttpResponse, ResponseError};
+use actix_web::{
+    Error as ActixError, FromRequest, HttpRequest, HttpResponse, ResponseError,
+};
+use de::Config as QsConfig;
 use error::Error as QsError;
 use serde::de;
 use std::fmt;
@@ -90,12 +93,18 @@ where
 
     #[inline]
     fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
-        let error_handler = req
-            .app_data::<QsQueryConfig>()
-            .map(|c| c.ehandler.clone())
-            .unwrap_or(None);
+        let query_config = req.app_data::<QsQueryConfig>();
 
-        super::from_str::<T>(req.query_string())
+        let error_handler =
+            query_config.map(|c| c.ehandler.clone()).unwrap_or(None);
+
+        let default_qsconfig = QsConfig::default();
+        let qsconfig = query_config
+            .map(|c| &c.qs_config)
+            .unwrap_or(&default_qsconfig);
+
+        qsconfig
+            .deserialize_str::<T>(req.query_string())
             .map(|val| Ok(QsQuery(val)))
             .unwrap_or_else(move |e| {
                 let e = if let Some(error_handler) = error_handler {
@@ -116,6 +125,7 @@ where
 /// extern crate actix_web;
 /// use actix_web::{error, web, App, FromRequest, HttpResponse};
 /// use serde_qs::actix::QsQuery;
+/// use serde_qs::Config as QsConfig;
 ///
 /// #[derive(Deserialize)]
 /// struct Info {
@@ -136,14 +146,17 @@ where
 ///                     error::InternalError::from_response(
 ///                         err, HttpResponse::Conflict().finish()).into()
 ///                 })
+///                 .qs_config(QsConfig::default())
 ///             }))
 ///             .route(web::post().to(index))
 ///     );
 /// }
 /// ```
+
 pub struct QsQueryConfig {
     ehandler:
         Option<Arc<Fn(QsError, &HttpRequest) -> ActixError + Send + Sync>>,
+    qs_config: QsConfig,
 }
 
 impl QsQueryConfig {
@@ -155,10 +168,19 @@ impl QsQueryConfig {
         self.ehandler = Some(Arc::new(f));
         self
     }
+
+    /// Set custom serialization parameters
+    pub fn qs_config(mut self, config: QsConfig) -> Self {
+        self.qs_config = config;
+        self
+    }
 }
 
 impl Default for QsQueryConfig {
     fn default() -> Self {
-        QsQueryConfig { ehandler: None }
+        QsQueryConfig {
+            ehandler: None,
+            qs_config: QsConfig::default(),
+        }
     }
 }
diff --git a/tests/test_actix.rs b/tests/test_actix.rs
index 09bc015..532fa7c 100644
--- a/tests/test_actix.rs
+++ b/tests/test_actix.rs
@@ -12,6 +12,7 @@ use actix_web::http::StatusCode;
 use actix_web::test::TestRequest;
 use actix_web::{FromRequest, HttpResponse};
 use qs::actix::{QsQuery, QsQueryConfig};
+use qs::Config as QsConfig;
 use serde::de::Error;
 
 fn from_str<'de, D, S>(deserializer: D) -> Result<S, D::Error>
@@ -91,3 +92,36 @@ fn test_composite_querystring_extractor() {
     assert_eq!(s.common.offset, 50);
     assert_eq!(s.common.remaining, true);
 }
+
+#[test]
+fn test_default_qs_config() {
+    let req = TestRequest::with_uri(
+        "/test?foo=1&bars%5B%5D=3&limit=100&offset=50&remaining=true",
+    )
+    .to_srv_request();
+    let (req, mut pl) = req.into_parts();
+
+    let e = QsQuery::<Query>::from_request(&req, &mut pl).unwrap_err();
+    assert_eq!(
+        e.as_response_error().error_response().status(),
+        StatusCode::BAD_REQUEST
+    );
+}
+
+#[test]
+fn test_custom_qs_config() {
+    let req = TestRequest::with_uri(
+        "/test?foo=1&bars%5B%5D=3&limit=100&offset=50&remaining=true",
+    )
+    .data(QsQueryConfig::default().qs_config(QsConfig::new(5, false)))
+    .to_srv_request();
+
+    let (req, mut pl) = req.into_parts();
+
+    let s = QsQuery::<Query>::from_request(&req, &mut pl).unwrap();
+    assert_eq!(s.foo, 1);
+    assert_eq!(s.bars, vec![3]);
+    assert_eq!(s.common.limit, 100);
+    assert_eq!(s.common.offset, 50);
+    assert_eq!(s.common.remaining, true);
+}
-- 
cgit v1.2.3