Skip to content

Commit

Permalink
Parse url query array like ids=[1,2,3]
Browse files Browse the repository at this point in the history
  • Loading branch information
chrislearn committed Oct 4, 2024
1 parent efb2b16 commit 0798c86
Show file tree
Hide file tree
Showing 6 changed files with 440 additions and 252 deletions.
2 changes: 2 additions & 0 deletions crates/core/src/extract/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ pub enum SourceParser {
MultiMap,
/// Json parser.
Json,
/// Url parser.
UrlQuery,
/// Smart parser.
Smart,
}
Expand Down
111 changes: 111 additions & 0 deletions crates/core/src/serde/cow_value.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
use std::borrow::Cow;

use serde::de::value::Error as ValError;
use serde::de::{Deserializer, Error as DeError, IntoDeserializer, Visitor};
use serde::forward_to_deserialize_any;

use super::ValueEnumAccess;

macro_rules! forward_cow_parsed_value {
($($ty:ident => $method:ident,)*) => {
$(
fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor<'de>
{
match self.0.parse::<$ty>() {
Ok(val) => val.into_deserializer().$method(visitor),
Err(e) => Err(DeError::custom(e))
}
}
)*
}
}

#[derive(Debug)]
pub(super) struct CowValue<'de>(pub(super) Cow<'de, str>);
impl<'de> IntoDeserializer<'de> for CowValue<'de> {
type Deserializer = Self;

fn into_deserializer(self) -> Self::Deserializer {
self
}
}

impl<'de> Deserializer<'de> for CowValue<'de> {
type Error = ValError;

#[inline]
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.0 {
Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
Cow::Owned(value) => visitor.visit_string(value),
}
}

#[inline]
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_some(self)
}

#[inline]
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_enum(ValueEnumAccess(self.0))
}

#[inline]
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}

forward_to_deserialize_any! {
char
str
string
unit
bytes
byte_buf
unit_struct
tuple_struct
struct
identifier
tuple
ignored_any
seq
map
}

forward_cow_parsed_value! {
bool => deserialize_bool,
u8 => deserialize_u8,
u16 => deserialize_u16,
u32 => deserialize_u32,
u64 => deserialize_u64,
i8 => deserialize_i8,
i16 => deserialize_i16,
i32 => deserialize_i32,
i64 => deserialize_i64,
f32 => deserialize_f32,
f64 => deserialize_f64,
}
}
Loading

0 comments on commit 0798c86

Please sign in to comment.