diff --git a/crates/core/src/serde/flat_value.rs b/crates/core/src/serde/flat_value.rs index e37dbaa06..665f8c606 100644 --- a/crates/core/src/serde/flat_value.rs +++ b/crates/core/src/serde/flat_value.rs @@ -171,10 +171,11 @@ impl<'de> Iterator for FlatParser<'de> { type Item = CowValue<'de>; fn next(&mut self) -> Option { - let mut in_quote = false; + let mut quote = None; let mut in_escape = false; let mut end = self.start; - for c in self.input[self.start..].chars() { + let mut in_next = false; + for c in self.input[self.start..].chars() { if in_escape { in_escape = false; continue; @@ -182,22 +183,62 @@ impl<'de> Iterator for FlatParser<'de> { match c { '\\' => { in_escape = true; + in_next = true; } - '"' => { - in_quote = !in_quote; + ' ' => { + if quote.is_none() { + self.start += 1; + } + } + '"' | '\'' => { + in_next = true; + if quote == Some(c) { + let item = Cow::Owned(self.input[self.start..end].to_string()); + self.start = end + 2; + return Some(CowValue(item)); + } else { + quote = Some(c); + self.start += 1; + + } } ',' | ']' => { - if !in_quote { - let item: Cow<'de, str> = - Cow::Owned(self.input[self.start..end].to_string()); + if quote.is_none() && in_next { + let item = Cow::Owned(self.input[self.start..end].to_string()); self.start = end + 1; return Some(CowValue(item)); } } - _ => {} + _ => { + in_next = true; + } } end += 1; } None } } + + +#[cfg(test)] +mod tests { + #[test] + fn test_flat_parser_1() { + let parser = super::FlatParser::new("[1,2, 3]".into()); + let mut iter = parser.into_iter(); + assert_eq!(iter.next().unwrap().0, "1"); + assert_eq!(iter.next().unwrap().0, "2"); + assert_eq!(iter.next().unwrap().0, "3"); + assert!(iter.next().is_none()); + } + #[test] + fn test_flat_parser_2() { + let parser = super::FlatParser::new(r#"['3', '2',"11","1,2"]"#.into()); + let mut iter = parser.into_iter(); + assert_eq!(iter.next().unwrap().0, "3"); + assert_eq!(iter.next().unwrap().0, "2"); + assert_eq!(iter.next().unwrap().0, "11"); + assert_eq!(iter.next().unwrap().0, "1,2"); + assert!(iter.next().is_none()); + } +} \ No newline at end of file diff --git a/crates/core/src/serde/request.rs b/crates/core/src/serde/request.rs index 5c11a3a37..c350a0d62 100644 --- a/crates/core/src/serde/request.rs +++ b/crates/core/src/serde/request.rs @@ -817,5 +817,39 @@ mod tests { ids: vec!["3".to_string(), "2".to_string(), "11".to_string()] } ); + let mut req = TestClient::get( + r#"http://127.0.0.1:5800/test/1234/param2v?ids=['3', '2',"11","1,2"]"#, + ) + .build(); + let data: RequestData = req.extract().await.unwrap(); + assert_eq!( + data, + RequestData { + ids: vec![ + "3".to_string(), + "2".to_string(), + "11".to_string(), + "1,2".to_string() + ] + } + ); + } + + #[tokio::test] + async fn test_de_request_url_array2() { + #[derive(Deserialize, Extractible, Eq, PartialEq, Debug)] + #[salvo(extract(default_source(from = "query")))] + struct RequestData { + ids: Vec, + } + let mut req = + TestClient::get("http://127.0.0.1:5800/test/1234/param2v?ids=[3,2,11]").build(); + let data: RequestData = req.extract().await.unwrap(); + assert_eq!( + data, + RequestData { + ids: vec![3, 2, 11] + } + ); } }