diff --git a/router/CHANGES.txt b/router/CHANGES.txt index 28482266..8b5e4411 100644 --- a/router/CHANGES.txt +++ b/router/CHANGES.txt @@ -1,5 +1,11 @@ # Changes +## [0.1.2] - 2019-04-07 + +* Export `Quoter` type + +* Allow to reset `Path` instance + ## [0.1.1] - 2019-04-03 * Get dynamic segment by name instead of iterator. diff --git a/router/Cargo.toml b/router/Cargo.toml index 53902746..e11c5db3 100644 --- a/router/Cargo.toml +++ b/router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "actix-router" -version = "0.1.1" +version = "0.1.2" authors = ["Nikolay Kim "] description = "Path router" keywords = ["actix"] diff --git a/router/src/lib.rs b/router/src/lib.rs index 18d9894b..6c3928de 100644 --- a/router/src/lib.rs +++ b/router/src/lib.rs @@ -39,7 +39,7 @@ impl> ResourcePath for string::String { mod url; #[cfg(feature = "http")] -pub use self::url::Url; +pub use self::url::{Quoter, Url}; #[cfg(feature = "http")] mod http_support { diff --git a/router/src/path.rs b/router/src/path.rs index 6e25519e..25060729 100644 --- a/router/src/path.rs +++ b/router/src/path.rs @@ -51,16 +51,19 @@ impl Path { } } + #[inline] /// Get reference to inner path instance pub fn get_ref(&self) -> &T { &self.path } + #[inline] /// Get mutable reference to inner path instance pub fn get_mut(&mut self) -> &mut T { &mut self.path } + #[inline] /// Path pub fn path(&self) -> &str { let skip = self.skip as usize; @@ -72,13 +75,22 @@ impl Path { } } - /// Reset inner path + #[inline] + /// Set new path pub fn set(&mut self, path: T) { self.skip = 0; self.path = path; self.segments.clear(); } + #[inline] + /// Reset state + pub fn reset(&mut self) { + self.skip = 0; + self.segments.clear(); + } + + #[inline] /// Skip first `n` chars in path pub fn skip(&mut self, n: u16) { self.skip = self.skip + n; @@ -99,11 +111,13 @@ impl Path { .push((Rc::new(name.to_string()), PathItem::Static(value))); } + #[inline] /// Check if there are any matched patterns pub fn is_empty(&self) -> bool { self.segments.is_empty() } + #[inline] /// Check number of extracted parameters pub fn len(&self) -> usize { self.segments.len() diff --git a/router/src/resource.rs b/router/src/resource.rs index e5cdfc83..e2c4cd5c 100644 --- a/router/src/resource.rs +++ b/router/src/resource.rs @@ -118,6 +118,7 @@ impl ResourceDef { &self.pattern } + #[inline] /// Check if path matchs this pattern? pub fn is_match(&self, path: &str) -> bool { match self.tp { diff --git a/router/src/url.rs b/router/src/url.rs index f5ed57e9..79fe2b63 100644 --- a/router/src/url.rs +++ b/router/src/url.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use crate::ResourcePath; #[allow(dead_code)] @@ -39,7 +37,7 @@ thread_local! { #[derive(Default, Clone, Debug)] pub struct Url { uri: http::Uri, - path: Option>, + path: Option, } impl Url { @@ -49,6 +47,13 @@ impl Url { Url { uri, path } } + pub fn with_quoter(uri: http::Uri, quoter: &Quoter) -> Url { + Url { + path: quoter.requote(uri.path().as_bytes()), + uri, + } + } + pub fn uri(&self) -> &http::Uri { &self.uri } @@ -61,19 +66,27 @@ impl Url { } } + #[inline] pub fn update(&mut self, uri: &http::Uri) { self.uri = uri.clone(); self.path = DEFAULT_QUOTER.with(|q| q.requote(uri.path().as_bytes())); } + + #[inline] + pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) { + self.uri = uri.clone(); + self.path = quoter.requote(uri.path().as_bytes()); + } } impl ResourcePath for Url { + #[inline] fn path(&self) -> &str { self.path() } } -pub(crate) struct Quoter { +pub struct Quoter { safe_table: [u8; 16], protected_table: [u8; 16], } @@ -108,7 +121,7 @@ impl Quoter { q } - pub fn requote(&self, val: &[u8]) -> Option> { + pub fn requote(&self, val: &[u8]) -> Option { let mut has_pct = 0; let mut pct = [b'%', 0, 0]; let mut idx = 0; @@ -160,7 +173,7 @@ impl Quoter { if let Some(data) = cloned { // Unsafe: we get data from http::Uri, which does utf-8 checks already // this code only decodes valid pct encoded values - Some(Rc::new(unsafe { String::from_utf8_unchecked(data) })) + Some(unsafe { String::from_utf8_unchecked(data) }) } else { None }