1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-30 21:04:35 +01:00

Revert "Support named parameters for ResourceDef::resource_path() in form of ((&k, &v), ...)"

This reverts commit b0d44198ba.
This commit is contained in:
Nikolay Kim 2019-12-31 15:14:53 +06:00
parent b0d44198ba
commit dcbcc40da2
4 changed files with 17 additions and 252 deletions

View File

@ -1,8 +1,6 @@
# Changes # Changes
## [0.3.0] - 2019-12-31 ## [0.2.4] - 2019-12-xx
* Support named parameters for `ResourceDef::resource_path()` in form of `((&k, &v), ...)`
## [0.2.3] - 2019-12-25 ## [0.2.3] - 2019-12-25

View File

@ -1,6 +1,6 @@
[package] [package]
name = "actix-router" name = "actix-router"
version = "0.3.0" version = "0.2.4"
authors = ["Nikolay Kim <fafhrd91@gmail.com>"] authors = ["Nikolay Kim <fafhrd91@gmail.com>"]
description = "Path router" description = "Path router"
keywords = ["actix"] keywords = ["actix"]
@ -18,11 +18,10 @@ path = "src/lib.rs"
default = ["http"] default = ["http"]
[dependencies] [dependencies]
bytestring = "0.1.2"
either = "1.5.3"
regex = "1.3.1" regex = "1.3.1"
log = "0.4.8"
serde = "1.0.104" serde = "1.0.104"
bytestring = "0.1.2"
log = "0.4.8"
http = { version="0.2.0", optional=true } http = { version="0.2.0", optional=true }
[dev-dependencies] [dev-dependencies]

View File

@ -4,8 +4,6 @@ mod path;
mod resource; mod resource;
mod router; mod router;
use either::Either;
pub use self::de::PathDeserializer; pub use self::de::PathDeserializer;
pub use self::path::Path; pub use self::path::Path;
pub use self::resource::ResourceDef; pub use self::resource::ResourceDef;
@ -37,127 +35,6 @@ impl ResourcePath for bytestring::ByteString {
} }
} }
pub trait ResourceElements {
fn elements<F, R>(self, for_each: F) -> Option<R>
where
F: FnMut(Either<&str, (&str, &str)>) -> Option<R>;
}
impl<'a, T: AsRef<str>> ResourceElements for &'a [T] {
fn elements<F, R>(self, mut for_each: F) -> Option<R>
where
F: FnMut(Either<&str, (&str, &str)>) -> Option<R>,
{
for t in self {
if let Some(res) = for_each(Either::Left(t.as_ref())) {
return Some(res);
}
}
None
}
}
impl<'a, U, I> ResourceElements for &'a U
where
&'a U: IntoIterator<Item = I>,
I: AsRef<str>,
{
fn elements<F, R>(self, mut for_each: F) -> Option<R>
where
F: FnMut(Either<&str, (&str, &str)>) -> Option<R>,
{
for t in self.into_iter() {
if let Some(res) = for_each(Either::Left(t.as_ref())) {
return Some(res);
}
}
None
}
}
impl<I> ResourceElements for Vec<I>
where
I: AsRef<str>,
{
fn elements<F, R>(self, mut for_each: F) -> Option<R>
where
F: FnMut(Either<&str, (&str, &str)>) -> Option<R>,
{
for t in self.iter() {
if let Some(res) = for_each(Either::Left(t.as_ref())) {
return Some(res);
}
}
None
}
}
impl<'a, K, V, S> ResourceElements for std::collections::HashMap<K, V, S>
where
K: AsRef<str>,
V: AsRef<str>,
S: std::hash::BuildHasher,
{
fn elements<F, R>(self, mut for_each: F) -> Option<R>
where
F: FnMut(Either<&str, (&str, &str)>) -> Option<R>,
{
for t in self.iter() {
if let Some(res) = for_each(Either::Right((t.0.as_ref(), t.1.as_ref()))) {
return Some(res);
}
}
None
}
}
#[rustfmt::skip]
mod _m {
use super::*;
// macro_rules! elements_tuple ({ $(($n:tt, $T:ident)),+} => {
// impl<$($T: AsRef<str>,)+> ResourceElements for ($($T,)+) {
// fn elements<F_, R_>(self, mut for_each: F_) -> Option<R_>
// where
// F_: FnMut(Either<&str, (&str, &str)>) -> Option<R_>,
// {
// $(
// if let Some(res) = for_each(Either::Left(self.$n.as_ref())) {
// return Some(res)
// }
// )+
// None
// }
// }
// });
macro_rules! elements_2tuple ({ $(($n:tt, $V:ident)),+} => {
impl<'a, $($V: AsRef<str>,)+> ResourceElements for ($((&'a str, $V),)+) {
fn elements<F_, R_>(self, mut for_each: F_) -> Option<R_>
where
F_: FnMut(Either<&str, (&str, &str)>) -> Option<R_>,
{
$(
if let Some(res) = for_each(Either::Right((self.$n.0, self.$n.1.as_ref()))) {
return Some(res)
}
)+
None
}
}
});
elements_2tuple!((0, A));
elements_2tuple!((0, A), (1, B));
elements_2tuple!((0, A), (1, B), (2, C));
elements_2tuple!((0, A), (1, B), (2, C), (3, D));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I));
elements_2tuple!((0, A), (1, B), (2, C), (3, D), (4, E), (5, F), (6, G), (7, H), (8, I), (9, J));
}
/// Helper trait for type that could be converted to path pattern /// Helper trait for type that could be converted to path pattern
pub trait IntoPattern { pub trait IntoPattern {
/// Signle patter /// Signle patter

View File

@ -1,11 +1,10 @@
use std::cmp::min; use std::cmp::min;
use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use regex::{escape, Regex, RegexSet}; use regex::{escape, Regex, RegexSet};
use crate::path::{Path, PathItem}; use crate::path::{Path, PathItem};
use crate::{IntoPattern, Resource, ResourceElements, ResourcePath}; use crate::{IntoPattern, Resource, ResourcePath};
const MAX_DYNAMIC_SEGMENTS: usize = 16; const MAX_DYNAMIC_SEGMENTS: usize = 16;
@ -464,66 +463,26 @@ impl ResourceDef {
} }
/// Build resource path from elements. Returns `true` on success. /// Build resource path from elements. Returns `true` on success.
pub fn resource_path<U: ResourceElements>(&self, path: &mut String, data: U) -> bool { pub fn resource_path<U, I>(&self, path: &mut String, elements: &mut U) -> bool
where
U: Iterator<Item = I>,
I: AsRef<str>,
{
match self.tp { match self.tp {
PatternType::Prefix(ref p) => path.push_str(p), PatternType::Prefix(ref p) => path.push_str(p),
PatternType::Static(ref p) => path.push_str(p), PatternType::Static(ref p) => path.push_str(p),
PatternType::Dynamic(..) => { PatternType::Dynamic(..) => {
let mut iter = self.elements.iter(); for el in &self.elements {
let mut map = HashMap::new(); match *el {
PatternElement::Str(ref s) => path.push_str(s),
let result = data.elements(|item| match item { PatternElement::Var(_) => {
either::Either::Left(val) => loop { if let Some(val) = elements.next() {
if let Some(el) = iter.next() { path.push_str(val.as_ref())
match *el {
PatternElement::Str(ref s) => path.push_str(s),
PatternElement::Var(_) => {
path.push_str(val.as_ref());
return None;
}
}
} else {
return Some(false);
}
},
either::Either::Right((name, val)) => {
map.insert(name.to_string(), val.to_string());
None
}
});
if result.is_some() {
return true;
} else {
if map.is_empty() {
// push static sections
loop {
if let Some(el) = iter.next() {
match *el {
PatternElement::Str(ref s) => path.push_str(s),
PatternElement::Var(_) => {
return false;
}
}
} else { } else {
break; return false;
}
}
} else {
for el in iter {
match *el {
PatternElement::Str(ref s) => path.push_str(s),
PatternElement::Var(ref name) => {
if let Some(val) = map.get(name) {
path.push_str(val);
continue;
}
return false;
}
} }
} }
} }
return true;
} }
} }
PatternType::DynamicSet(..) => { PatternType::DynamicSet(..) => {
@ -673,7 +632,6 @@ pub(crate) fn insert_slash(path: &str) -> String {
mod tests { mod tests {
use super::*; use super::*;
use http::Uri; use http::Uri;
use std::collections::HashMap;
use std::convert::TryFrom; use std::convert::TryFrom;
#[test] #[test]
@ -900,71 +858,4 @@ mod tests {
assert_eq!(&path["name"], "test2"); assert_eq!(&path["name"], "test2");
assert_eq!(&path[0], "test2"); assert_eq!(&path[0], "test2");
} }
#[test]
fn test_resource_path() {
let mut s = String::new();
let resource = ResourceDef::new("/user/{item1}/test");
assert!(resource.resource_path(&mut s, &["user1"]));
assert_eq!(s, "/user/user1/test");
let mut s = String::new();
assert!(resource.resource_path(&mut s, (("item1", "user1"),)));
assert_eq!(s, "/user/user1/test");
let mut s = String::new();
let resource = ResourceDef::new("/user/{item1}/{item2}/test");
assert!(resource.resource_path(&mut s, &["item", "item2"]));
assert_eq!(s, "/user/item/item2/test");
let mut s = String::new();
assert!(resource.resource_path(&mut s, (("item1", "item"), ("item2", "item2"))));
assert_eq!(s, "/user/item/item2/test");
let mut s = String::new();
let resource = ResourceDef::new("/user/{item1}/{item2}");
assert!(resource.resource_path(&mut s, &["item", "item2"]));
assert_eq!(s, "/user/item/item2");
let mut s = String::new();
assert!(resource.resource_path(&mut s, (("item1", "item"), ("item2", "item2"))));
assert_eq!(s, "/user/item/item2");
let mut s = String::new();
let resource = ResourceDef::new("/user/{item1}/{item2}/");
assert!(resource.resource_path(&mut s, &["item", "item2"]));
assert_eq!(s, "/user/item/item2/");
let mut s = String::new();
assert!(!resource.resource_path(&mut s, &["item"]));
let mut s = String::new();
assert!(resource.resource_path(&mut s, &["item", "item2"]));
assert_eq!(s, "/user/item/item2/");
assert!(!resource.resource_path(&mut s, &["item"]));
let mut s = String::new();
assert!(resource.resource_path(&mut s, vec!["item", "item2"]));
assert_eq!(s, "/user/item/item2/");
let mut s = String::new();
assert!(resource.resource_path(&mut s, &vec!["item", "item2"]));
assert_eq!(s, "/user/item/item2/");
let mut s = String::new();
assert!(resource.resource_path(&mut s, &vec!["item", "item2"][..]));
assert_eq!(s, "/user/item/item2/");
let mut map = HashMap::new();
map.insert("item1", "item");
map.insert("item2", "item2");
let mut s = String::new();
assert!(resource.resource_path(&mut s, map));
assert_eq!(s, "/user/item/item2/");
let mut s = String::new();
assert!(resource.resource_path(&mut s, (("item1", "item"), ("item2", "item2"))));
assert_eq!(s, "/user/item/item2/");
}
} }