Merge branch 'master' into router/fix/various

This commit is contained in:
Rob Ede 2021-07-23 16:57:59 +01:00 committed by GitHub
commit d3b8f4d1b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 10 deletions

View File

@ -1,10 +1,13 @@
# Changes # Changes
## Unreleased - 2021-xx-xx ## Unreleased - 2021-xx-xx
## 0.5.0-beta.1 - 2021-07-20
* Fix a bug in multi-patterns where static patterns are interpreted as regex. [#366] * Fix a bug in multi-patterns where static patterns are interpreted as regex. [#366]
* Introduce `ResourceDef::pattern_iter` to get an iterator over all patterns in a multi-pattern resource. [#373] * Introduce `ResourceDef::pattern_iter` to get an iterator over all patterns in a multi-pattern resource. [#373]
* Fix segment interpolation leaving `Path` in unintended state after matching. [#368] * Fix segment interpolation leaving `Path` in unintended state after matching. [#368]
* Fix `ResourceDef` `PartialEq` implementation. * Fix `ResourceDef` `PartialEq` implementation. [#373]
* Re-work `IntoPatterns` trait, adding a `Patterns` enum. [#372] * Re-work `IntoPatterns` trait, adding a `Patterns` enum. [#372]
* Implement `IntoPatterns` for `bytestring::ByteString`. [#372] * Implement `IntoPatterns` for `bytestring::ByteString`. [#372]
* Rename `Path::{len => segment_count}` to be more descriptive of it's purpose. [#370] * Rename `Path::{len => segment_count}` to be more descriptive of it's purpose. [#370]

View File

@ -1,12 +1,12 @@
[package] [package]
name = "actix-router" name = "actix-router"
version = "0.4.0" version = "0.5.0-beta.1"
authors = [ authors = [
"Nikolay Kim <fafhrd91@gmail.com>", "Nikolay Kim <fafhrd91@gmail.com>",
"Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com>", "Ali MJ Al-Nasrawy <alimjalnasrawy@gmail.com>",
"Rob Ede <robjtede@icloud.com>", "Rob Ede <robjtede@icloud.com>",
] ]
description = "Resource path matching library" description = "Resource path matching and router"
keywords = ["actix", "router", "routing"] keywords = ["actix", "router", "routing"]
repository = "https://github.com/actix/actix-net.git" repository = "https://github.com/actix/actix-net.git"
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"

View File

@ -1,4 +1,4 @@
//! Resource path matching library. //! Resource path matching and router.
#![deny(rust_2018_idioms, nonstandard_style)] #![deny(rust_2018_idioms, nonstandard_style)]
#![doc(html_logo_url = "https://actix.rs/img/logo.png")] #![doc(html_logo_url = "https://actix.rs/img/logo.png")]
@ -49,6 +49,15 @@ pub enum Patterns {
List(Vec<String>), List(Vec<String>),
} }
impl Patterns {
pub fn is_empty(&self) -> bool {
match self {
Patterns::Single(_) => false,
Patterns::List(pats) => pats.is_empty(),
}
}
}
/// Helper trait for type that could be converted to one or more path pattern. /// Helper trait for type that could be converted to one or more path pattern.
pub trait IntoPatterns { pub trait IntoPatterns {
fn patterns(&self) -> Patterns; fn patterns(&self) -> Patterns;
@ -78,6 +87,12 @@ impl IntoPatterns for bytestring::ByteString {
} }
} }
impl IntoPatterns for Patterns {
fn patterns(&self) -> Patterns {
self.clone()
}
}
impl<T: AsRef<str>> IntoPatterns for Vec<T> { impl<T: AsRef<str>> IntoPatterns for Vec<T> {
fn patterns(&self) -> Patterns { fn patterns(&self) -> Patterns {
let mut patterns = self.iter().map(|v| v.as_ref().to_owned()); let mut patterns = self.iter().map(|v| v.as_ref().to_owned());

View File

@ -12,7 +12,11 @@ pub struct ResourceInfo {
} }
/// Resource router. /// Resource router.
pub struct Router<T, U = ()>(Vec<(ResourceDef, T, Option<U>)>); // T is the resource itself
// U is any other data needed for routing like method guards
pub struct Router<T, U = ()> {
routes: Vec<(ResourceDef, T, Option<U>)>,
}
impl<T, U> Router<T, U> { impl<T, U> Router<T, U> {
pub fn build() -> RouterBuilder<T, U> { pub fn build() -> RouterBuilder<T, U> {
@ -28,7 +32,7 @@ impl<T, U> Router<T, U> {
{ {
profile_method!(recognize); profile_method!(recognize);
for item in self.0.iter() { for item in self.routes.iter() {
if item.0.capture_match_info(resource.resource_path()) { if item.0.capture_match_info(resource.resource_path()) {
return Some((&item.1, ResourceId(item.0.id()))); return Some((&item.1, ResourceId(item.0.id())));
} }
@ -44,7 +48,7 @@ impl<T, U> Router<T, U> {
{ {
profile_method!(recognize_mut); profile_method!(recognize_mut);
for item in self.0.iter_mut() { for item in self.routes.iter_mut() {
if item.0.capture_match_info(resource.resource_path()) { if item.0.capture_match_info(resource.resource_path()) {
return Some((&mut item.1, ResourceId(item.0.id()))); return Some((&mut item.1, ResourceId(item.0.id())));
} }
@ -61,7 +65,7 @@ impl<T, U> Router<T, U> {
{ {
profile_method!(recognize_checked); profile_method!(recognize_checked);
for item in self.0.iter() { for item in self.routes.iter() {
if item.0.capture_match_info_fn(resource, &check, &item.2) { if item.0.capture_match_info_fn(resource, &check, &item.2) {
return Some((&item.1, ResourceId(item.0.id()))); return Some((&item.1, ResourceId(item.0.id())));
} }
@ -82,7 +86,7 @@ impl<T, U> Router<T, U> {
{ {
profile_method!(recognize_mut_checked); profile_method!(recognize_mut_checked);
for item in self.0.iter_mut() { for item in self.routes.iter_mut() {
if item.0.capture_match_info_fn(resource, &check, &item.2) { if item.0.capture_match_info_fn(resource, &check, &item.2) {
return Some((&mut item.1, ResourceId(item.0.id()))); return Some((&mut item.1, ResourceId(item.0.id())));
} }
@ -129,7 +133,9 @@ impl<T, U> RouterBuilder<T, U> {
/// Finish configuration and create router instance. /// Finish configuration and create router instance.
pub fn finish(self) -> Router<T, U> { pub fn finish(self) -> Router<T, U> {
Router(self.resources) Router {
routes: self.resources,
}
} }
} }