1
0
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:
Nikolay Kim 2019-12-25 15:34:21 +04:00
parent 119027f822
commit bf0a9d2f6e
3 changed files with 82 additions and 36 deletions

View File

@ -2,6 +2,8 @@
## [0.2.1] - 2019-12-xx
* Add `IntoPatterns` trait
* Add multi-pattern resources
## [0.2.0] - 2019-12-07

View File

@ -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")]
mod url;

View File

@ -5,7 +5,7 @@ use std::rc::Rc;
use regex::{escape, Regex, RegexSet};
use crate::path::{Path, PathItem};
use crate::{Resource, ResourcePath};
use crate::{IntoPatterns, Resource, ResourcePath};
const MAX_DYNAMIC_SEGMENTS: usize = 16;
@ -39,20 +39,28 @@ impl ResourceDef {
/// Parse path pattern and create new `Pattern` instance.
///
/// Panics if path pattern is malformed.
pub fn new(path: &str) -> Self {
ResourceDef::with_prefix(path, false)
pub fn new<T: IntoPatterns>(path: T) -> Self {
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.
///
/// Panics if any of paths pattern is malformed. Every set element
/// 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 {
if set.is_single() {
ResourceDef::new(set)
} else {
let set = set.patterns();
let mut data = Vec::new();
let mut re_set = Vec::new();
for item in set {
let path = item.as_ref().to_owned();
for path in set {
let (pattern, _, _, len) = ResourceDef::parse(&path, false);
let re = match Regex::new(&pattern) {
@ -76,6 +84,7 @@ impl ResourceDef {
pattern: "".to_owned(),
}
}
}
/// Parse path pattern and create new `Pattern` instance.
///
@ -616,7 +625,7 @@ impl<'a> From<&'a str> for ResourceDef {
impl From<String> for ResourceDef {
fn from(path: String) -> ResourceDef {
ResourceDef::new(&path)
ResourceDef::new(path)
}
}
@ -700,14 +709,11 @@ mod tests {
#[test]
fn test_dynamic_set() {
let re = ResourceDef::new_set(
vec![
let re = ResourceDef::new_set(vec![
"/user/{id}",
"/v{version}/resource/{id}",
"/{id:[[:digit:]]{6}}",
]
.iter(),
);
]);
assert!(re.is_match("/user/profile"));
assert!(re.is_match("/user/2345"));
assert!(!re.is_match("/user/2345/"));