1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-27 17:52:56 +01:00

Changes the router to use atoms internally (#341)

This commit is contained in:
Armin Ronacher 2018-06-22 09:33:32 +02:00 committed by GitHub
parent 765c38e7b9
commit dda6ee95df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 26 deletions

View File

@ -16,6 +16,9 @@ license = "MIT/Apache-2.0"
exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"] exclude = [".gitignore", ".travis.yml", ".cargo/config", "appveyor.yml"]
build = "build.rs" build = "build.rs"
[package.metadata.docs.rs]
features = ["tls", "alpn", "session", "brotli", "flate2-c"]
[badges] [badges]
travis-ci = { repository = "actix/actix-web", branch = "master" } travis-ci = { repository = "actix/actix-web", branch = "master" }
appveyor = { repository = "fafhrd91/actix-web-hdy9d" } appveyor = { repository = "fafhrd91/actix-web-hdy9d" }
@ -46,9 +49,6 @@ flate2-c = ["flate2/miniz-sys"]
# rust backend for flate2 crate # rust backend for flate2 crate
flate2-rust = ["flate2/rust_backend"] flate2-rust = ["flate2/rust_backend"]
[package.metadata.docs.rs]
features = ["tls", "alpn", "session", "brotli", "flate2-c"]
[dependencies] [dependencies]
# actix = "0.6.1" # actix = "0.6.1"
actix = { git="https://github.com/actix/actix.git" } actix = { git="https://github.com/actix/actix.git" }
@ -103,6 +103,7 @@ tokio-tls = { version="0.1", optional = true }
# openssl # openssl
openssl = { version="0.10", optional = true } openssl = { version="0.10", optional = true }
tokio-openssl = { version="0.2", optional = true } tokio-openssl = { version="0.2", optional = true }
string_cache = "0.7.3"
[dev-dependencies] [dev-dependencies]
env_logger = "0.5" env_logger = "0.5"

View File

@ -114,6 +114,7 @@ extern crate net2;
extern crate parking_lot; extern crate parking_lot;
extern crate rand; extern crate rand;
extern crate slab; extern crate slab;
extern crate string_cache;
extern crate tokio; extern crate tokio;
extern crate tokio_io; extern crate tokio_io;
extern crate tokio_reactor; extern crate tokio_reactor;

View File

@ -5,6 +5,7 @@ use std::str::FromStr;
use http::StatusCode; use http::StatusCode;
use smallvec::SmallVec; use smallvec::SmallVec;
use string_cache::DefaultAtom as Atom;
use error::{InternalError, ResponseError, UriSegmentError}; use error::{InternalError, ResponseError, UriSegmentError};
use uri::Url; use uri::Url;
@ -19,9 +20,9 @@ pub trait FromParam: Sized {
fn from_param(s: &str) -> Result<Self, Self::Err>; fn from_param(s: &str) -> Result<Self, Self::Err>;
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone)]
pub(crate) enum ParamItem { pub(crate) enum ParamItem {
Static(&'static str), Static(Atom),
UrlSegment(u16, u16), UrlSegment(u16, u16),
} }
@ -32,7 +33,7 @@ pub(crate) enum ParamItem {
pub struct Params { pub struct Params {
url: Url, url: Url,
pub(crate) tail: u16, pub(crate) tail: u16,
segments: SmallVec<[(&'static str, ParamItem); 3]>, segments: SmallVec<[(Atom, ParamItem); 3]>,
} }
impl Params { impl Params {
@ -56,12 +57,12 @@ impl Params {
self.tail = tail; self.tail = tail;
} }
pub(crate) fn add(&mut self, name: &'static str, value: ParamItem) { pub(crate) fn add(&mut self, name: Atom, value: ParamItem) {
self.segments.push((name, value)); self.segments.push((name, value));
} }
pub(crate) fn add_static(&mut self, name: &'static str, value: &'static str) { pub(crate) fn add_static(&mut self, name: &str, value: &'static str) {
self.segments.push((name, ParamItem::Static(value))); self.segments.push((Atom::from(name), ParamItem::Static(Atom::from(value))));
} }
/// Check if there are any matched patterns /// Check if there are any matched patterns
@ -77,9 +78,9 @@ impl Params {
/// Get matched parameter by name without type conversion /// Get matched parameter by name without type conversion
pub fn get(&self, key: &str) -> Option<&str> { pub fn get(&self, key: &str) -> Option<&str> {
for item in self.segments.iter() { for item in self.segments.iter() {
if key == item.0 { if key == &item.0 {
return match item.1 { return match item.1 {
ParamItem::Static(s) => Some(s), ParamItem::Static(ref s) => Some(&s),
ParamItem::UrlSegment(s, e) => { ParamItem::UrlSegment(s, e) => {
Some(&self.url.path()[(s as usize)..(e as usize)]) Some(&self.url.path()[(s as usize)..(e as usize)])
} }
@ -138,13 +139,13 @@ impl<'a> Iterator for ParamsIter<'a> {
if self.idx < self.params.len() { if self.idx < self.params.len() {
let idx = self.idx; let idx = self.idx;
let res = match self.params.segments[idx].1 { let res = match self.params.segments[idx].1 {
ParamItem::Static(s) => s, ParamItem::Static(ref s) => &s,
ParamItem::UrlSegment(s, e) => { ParamItem::UrlSegment(s, e) => {
&self.params.url.path()[(s as usize)..(e as usize)] &self.params.url.path()[(s as usize)..(e as usize)]
} }
}; };
self.idx += 1; self.idx += 1;
return Some((self.params.segments[idx].0, res)); return Some((&self.params.segments[idx].0, res));
} }
None None
} }
@ -164,7 +165,7 @@ impl<'a> Index<usize> for &'a Params {
fn index(&self, idx: usize) -> &str { fn index(&self, idx: usize) -> &str {
match self.segments[idx].1 { match self.segments[idx].1 {
ParamItem::Static(s) => s, ParamItem::Static(ref s) => &s,
ParamItem::UrlSegment(s, e) => &self.url.path()[(s as usize)..(e as usize)], ParamItem::UrlSegment(s, e) => &self.url.path()[(s as usize)..(e as usize)],
} }
} }

View File

@ -1,6 +1,5 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::mem;
use std::rc::Rc; use std::rc::Rc;
use regex::{escape, Regex}; use regex::{escape, Regex};
@ -12,6 +11,8 @@ use param::ParamItem;
use resource::ResourceHandler; use resource::ResourceHandler;
use server::ServerSettings; use server::ServerSettings;
use string_cache::DefaultAtom as Atom;
/// Interface for application router. /// Interface for application router.
pub struct Router(Rc<Inner>); pub struct Router(Rc<Inner>);
@ -144,7 +145,7 @@ enum PatternElement {
enum PatternType { enum PatternType {
Static(String), Static(String),
Prefix(String), Prefix(String),
Dynamic(Regex, Vec<&'static str>, usize), Dynamic(Regex, Vec<Atom>, usize),
} }
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -221,12 +222,7 @@ impl Resource {
let names = re let names = re
.capture_names() .capture_names()
.filter_map(|name| { .filter_map(|name| {
name.map(|name| { name.map(|name| Atom::from(name))
let name = name.to_owned();
let s: &'static str = unsafe { mem::transmute(name.as_str()) };
mem::forget(name);
s
})
}) })
.collect(); .collect();
PatternType::Dynamic(re, names, len) PatternType::Dynamic(re, names, len)
@ -316,8 +312,8 @@ impl Resource {
let len = req.path().len(); let len = req.path().len();
let params = req.match_info_mut(); let params = req.match_info_mut();
params.set_tail(len as u16); params.set_tail(len as u16);
for (idx, segment) in segments.iter().enumerate() { for (idx, segment) in segments.into_iter().enumerate() {
params.add(names[idx], *segment); params.add(names[idx].clone(), segment);
} }
true true
} }
@ -382,8 +378,8 @@ impl Resource {
let params = req.match_info_mut(); let params = req.match_info_mut();
params.set_tail(tail_len as u16); params.set_tail(tail_len as u16);
for (idx, segment) in segments.iter().enumerate() { for (idx, segment) in segments.into_iter().enumerate() {
params.add(names[idx], *segment); params.add(names[idx].clone(), segment);
} }
Some(tail_len) Some(tail_len)
} }