mirror of
https://github.com/fafhrd91/actix-net
synced 2025-01-31 09:12:08 +01:00
Add IntoPatterns trait
This commit is contained in:
parent
119027f822
commit
bf0a9d2f6e
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## [0.2.1] - 2019-12-xx
|
## [0.2.1] - 2019-12-xx
|
||||||
|
|
||||||
|
* Add `IntoPatterns` trait
|
||||||
|
|
||||||
* Add multi-pattern resources
|
* Add multi-pattern resources
|
||||||
|
|
||||||
## [0.2.0] - 2019-12-07
|
## [0.2.0] - 2019-12-07
|
||||||
|
@ -35,6 +35,44 @@ impl ResourcePath for bytestring::ByteString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper trait for type that could be converted to path pattern
|
||||||
|
pub trait IntoPatterns {
|
||||||
|
/// Signle patter
|
||||||
|
fn is_single(&self) -> bool;
|
||||||
|
|
||||||
|
fn patterns(&self) -> Vec<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoPatterns for String {
|
||||||
|
fn is_single(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn patterns(&self) -> Vec<String> {
|
||||||
|
vec![self.clone()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> IntoPatterns for &'a str {
|
||||||
|
fn is_single(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn patterns(&self) -> Vec<String> {
|
||||||
|
vec![self.to_string()]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: AsRef<str>> IntoPatterns for Vec<T> {
|
||||||
|
fn is_single(&self) -> bool {
|
||||||
|
self.len() == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn patterns(&self) -> Vec<String> {
|
||||||
|
self.into_iter().map(|v| v.as_ref().to_string()).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
mod url;
|
mod url;
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ use std::rc::Rc;
|
|||||||
use regex::{escape, Regex, RegexSet};
|
use regex::{escape, Regex, RegexSet};
|
||||||
|
|
||||||
use crate::path::{Path, PathItem};
|
use crate::path::{Path, PathItem};
|
||||||
use crate::{Resource, ResourcePath};
|
use crate::{IntoPatterns, Resource, ResourcePath};
|
||||||
|
|
||||||
const MAX_DYNAMIC_SEGMENTS: usize = 16;
|
const MAX_DYNAMIC_SEGMENTS: usize = 16;
|
||||||
|
|
||||||
@ -39,41 +39,50 @@ impl ResourceDef {
|
|||||||
/// Parse path pattern and create new `Pattern` instance.
|
/// Parse path pattern and create new `Pattern` instance.
|
||||||
///
|
///
|
||||||
/// Panics if path pattern is malformed.
|
/// Panics if path pattern is malformed.
|
||||||
pub fn new(path: &str) -> Self {
|
pub fn new<T: IntoPatterns>(path: T) -> Self {
|
||||||
ResourceDef::with_prefix(path, false)
|
if path.is_single() {
|
||||||
|
let patterns = path.patterns();
|
||||||
|
ResourceDef::with_prefix(&patterns[0], false)
|
||||||
|
} else {
|
||||||
|
ResourceDef::new_set(path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse path pattern and create new `Pattern` instance.
|
/// Parse path pattern and create new `Pattern` instance.
|
||||||
///
|
///
|
||||||
/// Panics if any of paths pattern is malformed. Every set element
|
/// Panics if any of paths pattern is malformed. Every set element
|
||||||
/// must contain same set of capture elements.
|
/// must contain same set of capture elements.
|
||||||
pub fn new_set<T: Iterator<Item = U>, U: AsRef<str>>(set: T) -> Self {
|
pub fn new_set<T: IntoPatterns>(set: T) -> Self {
|
||||||
let mut data = Vec::new();
|
if set.is_single() {
|
||||||
let mut re_set = Vec::new();
|
ResourceDef::new(set)
|
||||||
|
} else {
|
||||||
|
let set = set.patterns();
|
||||||
|
let mut data = Vec::new();
|
||||||
|
let mut re_set = Vec::new();
|
||||||
|
|
||||||
for item in set {
|
for path in set {
|
||||||
let path = item.as_ref().to_owned();
|
let (pattern, _, _, len) = ResourceDef::parse(&path, false);
|
||||||
let (pattern, _, _, len) = ResourceDef::parse(&path, false);
|
|
||||||
|
|
||||||
let re = match Regex::new(&pattern) {
|
let re = match Regex::new(&pattern) {
|
||||||
Ok(re) => re,
|
Ok(re) => re,
|
||||||
Err(err) => panic!("Wrong path pattern: \"{}\" {}", path, err),
|
Err(err) => panic!("Wrong path pattern: \"{}\" {}", path, err),
|
||||||
};
|
};
|
||||||
// actix creates one router per thread
|
// actix creates one router per thread
|
||||||
let names: Vec<_> = re
|
let names: Vec<_> = re
|
||||||
.capture_names()
|
.capture_names()
|
||||||
.filter_map(|name| name.map(|name| Rc::new(name.to_owned())))
|
.filter_map(|name| name.map(|name| Rc::new(name.to_owned())))
|
||||||
.collect();
|
.collect();
|
||||||
data.push((re, names, len));
|
data.push((re, names, len));
|
||||||
re_set.push(pattern);
|
re_set.push(pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceDef {
|
ResourceDef {
|
||||||
id: 0,
|
id: 0,
|
||||||
tp: PatternType::DynamicSet(RegexSet::new(re_set).unwrap(), data),
|
tp: PatternType::DynamicSet(RegexSet::new(re_set).unwrap(), data),
|
||||||
elements: Vec::new(),
|
elements: Vec::new(),
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
pattern: "".to_owned(),
|
pattern: "".to_owned(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -616,7 +625,7 @@ impl<'a> From<&'a str> for ResourceDef {
|
|||||||
|
|
||||||
impl From<String> for ResourceDef {
|
impl From<String> for ResourceDef {
|
||||||
fn from(path: String) -> ResourceDef {
|
fn from(path: String) -> ResourceDef {
|
||||||
ResourceDef::new(&path)
|
ResourceDef::new(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,14 +709,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dynamic_set() {
|
fn test_dynamic_set() {
|
||||||
let re = ResourceDef::new_set(
|
let re = ResourceDef::new_set(vec![
|
||||||
vec![
|
"/user/{id}",
|
||||||
"/user/{id}",
|
"/v{version}/resource/{id}",
|
||||||
"/v{version}/resource/{id}",
|
"/{id:[[:digit:]]{6}}",
|
||||||
"/{id:[[:digit:]]{6}}",
|
]);
|
||||||
]
|
|
||||||
.iter(),
|
|
||||||
);
|
|
||||||
assert!(re.is_match("/user/profile"));
|
assert!(re.is_match("/user/profile"));
|
||||||
assert!(re.is_match("/user/2345"));
|
assert!(re.is_match("/user/2345"));
|
||||||
assert!(!re.is_match("/user/2345/"));
|
assert!(!re.is_match("/user/2345/"));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user