1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-27 15:42:57 +01:00
This commit is contained in:
Rob Ede 2020-12-23 19:43:40 +00:00
parent 4e4122b702
commit 8666c4063f
No known key found for this signature in database
GPG Key ID: C2A3B36E841A91E6
4 changed files with 149 additions and 20 deletions

View File

@ -1,3 +1,5 @@
use std::fmt;
use serde::de::{self, Deserializer, Error as DeError, Visitor}; use serde::de::{self, Deserializer, Error as DeError, Visitor};
use serde::forward_to_deserialize_any; use serde::forward_to_deserialize_any;
@ -42,17 +44,24 @@ macro_rules! parse_single_value {
}; };
} }
pub struct PathDeserializer<'de, T: ResourcePath> { #[derive(Debug)]
pub struct PathDeserializer<'de, T: ResourcePath + fmt::Debug> {
path: &'de Path<T>, path: &'de Path<T>,
} }
impl<'de, T: ResourcePath + 'de> PathDeserializer<'de, T> { impl<'de, T> PathDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug + 'de,
{
pub fn new(path: &'de Path<T>) -> Self { pub fn new(path: &'de Path<T>) -> Self {
PathDeserializer { path } PathDeserializer { path }
} }
} }
impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T> { impl<'de, T> Deserializer<'de> for PathDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug + 'de,
{
type Error = de::value::Error; type Error = de::value::Error;
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error> fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@ -103,6 +112,7 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("heres my newtype");
visitor.visit_newtype_struct(self) visitor.visit_newtype_struct(self)
} }
@ -154,15 +164,19 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
fn deserialize_enum<V>( fn deserialize_enum<V>(
self, self,
_: &'static str, _: &'static str,
_: &'static [&'static str], variants: &'static [&'static str],
visitor: V, visitor: V,
) -> Result<V::Value, Self::Error> ) -> Result<V::Value, Self::Error>
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("variants: {:?}", &variants);
if self.path.is_empty() { if self.path.is_empty() {
Err(de::value::Error::custom("expected at least one parameters")) Err(de::value::Error::custom("expected at least one parameters"))
} else { } else {
eprintln!("{:?}", &self.path[0]);
visitor.visit_enum(ValueEnum { visitor.visit_enum(ValueEnum {
value: &self.path[0], value: &self.path[0],
}) })
@ -191,7 +205,16 @@ impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>
}) })
} }
unsupported_type!(deserialize_any, "'any'"); fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.path[0].parse::<u64>() {
Ok(int) => visitor.visit_u64(int),
Err(_) => visitor.visit_str(&self.path[0]),
}
}
unsupported_type!(deserialize_bytes, "bytes"); unsupported_type!(deserialize_bytes, "bytes");
unsupported_type!(deserialize_option, "Option<T>"); unsupported_type!(deserialize_option, "Option<T>");
unsupported_type!(deserialize_identifier, "identifier"); unsupported_type!(deserialize_identifier, "identifier");
@ -218,7 +241,10 @@ struct ParamsDeserializer<'de, T: ResourcePath> {
current: Option<(&'de str, &'de str)>, current: Option<(&'de str, &'de str)>,
} }
impl<'de, T: ResourcePath> de::MapAccess<'de> for ParamsDeserializer<'de, T> { impl<'de, T> de::MapAccess<'de> for ParamsDeserializer<'de, T>
where
T: ResourcePath + fmt::Debug,
{
type Error = de::value::Error; type Error = de::value::Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
@ -262,6 +288,7 @@ impl<'de> Deserializer<'de> for Key<'de> {
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("Key::deserialize_any");
Err(de::value::Error::custom("Unexpected")) Err(de::value::Error::custom("Unexpected"))
} }
@ -312,6 +339,7 @@ impl<'de> Deserializer<'de> for Value<'de> {
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("Value::deserialize_ignored_any");
visitor.visit_unit() visitor.visit_unit()
} }
@ -418,7 +446,10 @@ struct ParamsSeq<'de, T: ResourcePath> {
params: PathIter<'de, T>, params: PathIter<'de, T>,
} }
impl<'de, T: ResourcePath> de::SeqAccess<'de> for ParamsSeq<'de, T> { impl<'de, T> de::SeqAccess<'de> for ParamsSeq<'de, T>
where
T: ResourcePath + fmt::Debug,
{
type Error = de::value::Error; type Error = de::value::Error;
fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, Self::Error> fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, Self::Error>
@ -432,8 +463,10 @@ impl<'de, T: ResourcePath> de::SeqAccess<'de> for ParamsSeq<'de, T> {
} }
} }
#[derive(Debug)]
struct ValueEnum<'de> { struct ValueEnum<'de> {
value: &'de str, value: &'de str,
// todo there maybe must be some state here to decide on which variant to use
} }
impl<'de> de::EnumAccess<'de> for ValueEnum<'de> { impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
@ -444,6 +477,9 @@ impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
where where
V: de::DeserializeSeed<'de>, V: de::DeserializeSeed<'de>,
{ {
// eprintln!("seed: {:?}", &seed);
eprintln!("value: {:?}", &self.value);
Ok((seed.deserialize(Key { key: self.value })?, UnitVariant)) Ok((seed.deserialize(Key { key: self.value })?, UnitVariant))
} }
} }
@ -454,6 +490,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
type Error = de::value::Error; type Error = de::value::Error;
fn unit_variant(self) -> Result<(), Self::Error> { fn unit_variant(self) -> Result<(), Self::Error> {
eprintln!("try unit variant");
Ok(()) Ok(())
} }
@ -461,6 +498,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
eprintln!("try newtype variant");
Err(de::value::Error::custom("not supported")) Err(de::value::Error::custom("not supported"))
} }
@ -468,6 +506,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("try tuple variant");
Err(de::value::Error::custom("not supported")) Err(de::value::Error::custom("not supported"))
} }
@ -479,6 +518,7 @@ impl<'de> de::VariantAccess<'de> for UnitVariant {
where where
V: Visitor<'de>, V: Visitor<'de>,
{ {
eprintln!("try struct variant");
Err(de::value::Error::custom("not supported")) Err(de::value::Error::custom("not supported"))
} }
} }
@ -512,6 +552,11 @@ mod tests {
value: u32, value: u32,
} }
#[derive(Debug, Deserialize)]
struct Test3 {
val: TestEnum,
}
#[derive(Debug, Deserialize, PartialEq)] #[derive(Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
enum TestEnum { enum TestEnum {
@ -519,9 +564,72 @@ mod tests {
Val2, Val2,
} }
#[derive(Debug, Deserialize)] #[derive(Clone, Debug, PartialEq, Eq)]
struct Test3 { pub enum TestEnum2 {
val: TestEnum, Int(u32),
String(String),
}
#[allow(non_snake_case)]
mod __TestEnum2 {
use std::fmt;
use serde::{
export::{Err as SErr, Ok as SOk, Result as SResult},
private::de::{Content, ContentRefDeserializer},
Deserialize,
};
use super::TestEnum2;
impl<'de> serde::Deserialize<'de> for TestEnum2 {
fn deserialize<D>(deserializer: D) -> SResult<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
eprintln!(
"!!derive!! deserializer: {:?}",
&deserializer.is_human_readable()
);
let content = match <Content<'_> as Deserialize>::deserialize(deserializer) {
SOk(val) => {
eprintln!("!!derive!! content val: {:?}", &val);
val
}
SErr(err) => {
eprintln!("!!derive!! content err: {:?}", &err);
return SErr(err);
}
};
let cnt1 = ContentRefDeserializer::<D::Error>::new(&content);
let de1 = <u32 as Deserialize>::deserialize(cnt1);
// eprintln!("!!derive!! cnt1: {:?}", &cnt1);
eprintln!("!!derive!! de1: {:?}", &de1);
if let SOk(ok) = SResult::map(de1, TestEnum2::Int) {
eprintln!("!!derive!! de1 map ok: {:?}", &ok);
return SOk(ok);
}
let cnt2 = ContentRefDeserializer::<D::Error>::new(&content);
let de2 = <String as Deserialize>::deserialize(cnt2);
// eprintln!("!!derive!! cnt2: {:?}", &cnt2);
eprintln!("!!derive!! de2: {:?}", &de2);
if let SOk(ok) = SResult::map(de2, TestEnum2::String) {
eprintln!("!!derive!! de2 map ok: {:?}", &ok);
return SOk(ok);
}
SErr(serde::de::Error::custom(
"data did not match any variant of untagged enum TestEnum2",
))
}
}
} }
#[test] #[test]
@ -591,6 +699,16 @@ mod tests {
let i: TestEnum = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap(); let i: TestEnum = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum::Val1); assert_eq!(i, TestEnum::Val1);
let mut path = Path::new("/22/");
assert!(router.recognize(&mut path).is_some());
let i: TestEnum2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum2::Int(22));
let mut path = Path::new("/abc/");
assert!(router.recognize(&mut path).is_some());
let i: TestEnum2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
assert_eq!(i, TestEnum2::String("abc".to_owned()));
let mut router = Router::<()>::build(); let mut router = Router::<()>::build();
router.path("/{val1}/{val2}/", ()); router.path("/{val1}/{val2}/", ());
let router = router.finish(); let router = router.finish();

View File

@ -1,4 +1,4 @@
use std::ops::Index; use std::{fmt, ops::Index};
use serde::de; use serde::de;
@ -41,7 +41,10 @@ impl<T: Clone> Clone for Path<T> {
} }
} }
impl<T: ResourcePath> Path<T> { impl<T> Path<T>
where
T: ResourcePath + fmt::Debug,
{
pub fn new(path: T) -> Path<T> { pub fn new(path: T) -> Path<T> {
Path { Path {
path, path,
@ -177,7 +180,10 @@ pub struct PathIter<'a, T> {
params: &'a Path<T>, params: &'a Path<T>,
} }
impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> { impl<'a, T> Iterator for PathIter<'a, T>
where
T: ResourcePath + fmt::Debug,
{
type Item = (&'a str, &'a str); type Item = (&'a str, &'a str);
#[inline] #[inline]
@ -195,7 +201,10 @@ impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> {
} }
} }
impl<'a, T: ResourcePath> Index<&'a str> for Path<T> { impl<'a, T> Index<&'a str> for Path<T>
where
T: ResourcePath + fmt::Debug,
{
type Output = str; type Output = str;
fn index(&self, name: &'a str) -> &str { fn index(&self, name: &'a str) -> &str {

View File

@ -1,6 +1,6 @@
use std::cmp::min;
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::{cmp::min, fmt};
use regex::{escape, Regex, RegexSet}; use regex::{escape, Regex, RegexSet};
@ -241,7 +241,7 @@ impl ResourceDef {
} }
/// Is the given path and parameters a match against this pattern. /// Is the given path and parameters a match against this pattern.
pub fn match_path<T: ResourcePath>(&self, path: &mut Path<T>) -> bool { pub fn match_path<T: ResourcePath + fmt::Debug>(&self, path: &mut Path<T>) -> bool {
match self.tp { match self.tp {
PatternType::Static(ref s) => { PatternType::Static(ref s) => {
if s == path.path() { if s == path.path() {
@ -345,7 +345,7 @@ impl ResourceDef {
user_data: &Option<U>, user_data: &Option<U>,
) -> bool ) -> bool
where where
T: ResourcePath, T: ResourcePath + fmt::Debug,
R: Resource<T>, R: Resource<T>,
F: Fn(&R, &Option<U>) -> bool, F: Fn(&R, &Option<U>) -> bool,
{ {

View File

@ -1,3 +1,5 @@
use std::fmt;
use crate::{IntoPattern, Resource, ResourceDef, ResourcePath}; use crate::{IntoPattern, Resource, ResourceDef, ResourcePath};
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -22,7 +24,7 @@ impl<T, U> Router<T, U> {
pub fn recognize<R, P>(&self, resource: &mut R) -> Option<(&T, ResourceId)> pub fn recognize<R, P>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
where where
R: Resource<P>, R: Resource<P>,
P: ResourcePath, P: ResourcePath + fmt::Debug,
{ {
for item in self.0.iter() { for item in self.0.iter() {
if item.0.match_path(resource.resource_path()) { if item.0.match_path(resource.resource_path()) {
@ -35,7 +37,7 @@ impl<T, U> Router<T, U> {
pub fn recognize_mut<R, P>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)> pub fn recognize_mut<R, P>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)>
where where
R: Resource<P>, R: Resource<P>,
P: ResourcePath, P: ResourcePath + fmt::Debug,
{ {
for item in self.0.iter_mut() { for item in self.0.iter_mut() {
if item.0.match_path(resource.resource_path()) { if item.0.match_path(resource.resource_path()) {
@ -53,7 +55,7 @@ impl<T, U> Router<T, U> {
where where
F: Fn(&R, &Option<U>) -> bool, F: Fn(&R, &Option<U>) -> bool,
R: Resource<P>, R: Resource<P>,
P: ResourcePath, P: ResourcePath + fmt::Debug,
{ {
for item in self.0.iter_mut() { for item in self.0.iter_mut() {
if item.0.match_path_checked(resource, &check, &item.2) { if item.0.match_path_checked(resource, &check, &item.2) {