1
0
mirror of https://github.com/actix/actix-extras.git synced 2024-12-01 02:44:37 +01:00

Changes a leaked box into an Rc<String> and makes resource() return an Option (#343)

This commit is contained in:
Armin Ronacher 2018-06-23 08:16:52 +02:00 committed by GitHub
parent ff0ab733e4
commit a5369aed8b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 33 deletions

View File

@ -94,10 +94,6 @@ impl HttpInnerMessage {
} }
} }
lazy_static! {
static ref RESOURCE: Resource = Resource::unset();
}
/// An HTTP Request /// An HTTP Request
pub struct HttpRequest<S = ()>(SharedHttpInnerMessage, Option<Rc<S>>, Option<Router>); pub struct HttpRequest<S = ()>(SharedHttpInnerMessage, Option<Rc<S>>, Option<Router>);
@ -345,13 +341,13 @@ impl<S> HttpRequest<S> {
/// This method returns reference to matched `Resource` object. /// This method returns reference to matched `Resource` object.
#[inline] #[inline]
pub fn resource(&self) -> &Resource { pub fn resource(&self) -> Option<&Resource> {
if let Some(ref router) = self.2 { if let Some(ref router) = self.2 {
if let RouterResource::Normal(idx) = self.as_ref().resource { if let RouterResource::Normal(idx) = self.as_ref().resource {
return router.get_resource(idx as usize); return Some(router.get_resource(idx as usize));
} }
} }
&*RESOURCE None
} }
pub(crate) fn set_resource(&mut self, res: usize) { pub(crate) fn set_resource(&mut self, res: usize) {

View File

@ -1,4 +1,5 @@
use std; use std;
use std::rc::Rc;
use std::ops::Index; use std::ops::Index;
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
@ -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<[(Rc<String>, 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: Rc<String>, 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((Rc::new(name.to_string()), ParamItem::Static(value)));
} }
/// Check if there are any matched patterns /// Check if there are any matched patterns
@ -77,7 +78,7 @@ 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.as_str() {
return match item.1 { return match item.1 {
ParamItem::Static(ref s) => Some(&s), ParamItem::Static(ref s) => Some(&s),
ParamItem::UrlSegment(s, e) => { ParamItem::UrlSegment(s, e) => {

View File

@ -143,7 +143,7 @@ enum PatternElement {
enum PatternType { enum PatternType {
Static(String), Static(String),
Prefix(String), Prefix(String),
Dynamic(Regex, Vec<&'static str>, usize), Dynamic(Regex, Vec<Rc<String>>, usize),
} }
#[derive(Debug, Copy, Clone, PartialEq)] #[derive(Debug, Copy, Clone, PartialEq)]
@ -195,17 +195,6 @@ impl Resource {
resource resource
} }
/// Unset resource type
pub(crate) fn unset() -> Resource {
Resource {
tp: PatternType::Static("".to_owned()),
rtp: ResourceType::Unset,
name: "".to_owned(),
pattern: "".to_owned(),
elements: Vec::new(),
}
}
/// Parse path pattern and create new `Resource` instance with custom prefix /// Parse path pattern and create new `Resource` instance with custom prefix
pub fn with_prefix(name: &str, path: &str, prefix: &str, for_prefix: bool) -> Self { pub fn with_prefix(name: &str, path: &str, prefix: &str, for_prefix: bool) -> Self {
let (pattern, elements, is_dynamic, len) = let (pattern, elements, is_dynamic, len) =
@ -220,11 +209,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| Rc::new(name.to_owned()))
let s: &'static str =
Box::leak(name.to_owned().into_boxed_str());
s
})
}) })
.collect(); .collect();
PatternType::Dynamic(re, names, len) PatternType::Dynamic(re, names, len)
@ -315,7 +300,7 @@ impl Resource {
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.into_iter().enumerate() { for (idx, segment) in segments.into_iter().enumerate() {
params.add(names[idx], segment); params.add(names[idx].clone(), segment);
} }
true true
} }
@ -381,7 +366,7 @@ 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.into_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)
} }
@ -774,13 +759,13 @@ mod tests {
let mut req = let mut req =
TestRequest::with_uri("/index.json").finish_with_router(router.clone()); TestRequest::with_uri("/index.json").finish_with_router(router.clone());
assert_eq!(router.recognize(&mut req), Some(0)); assert_eq!(router.recognize(&mut req), Some(0));
let resource = req.resource(); let resource = req.resource().unwrap();
assert_eq!(resource.name(), "r1"); assert_eq!(resource.name(), "r1");
let mut req = let mut req =
TestRequest::with_uri("/test.json").finish_with_router(router.clone()); TestRequest::with_uri("/test.json").finish_with_router(router.clone());
assert_eq!(router.recognize(&mut req), Some(1)); assert_eq!(router.recognize(&mut req), Some(1));
let resource = req.resource(); let resource = req.resource().unwrap();
assert_eq!(resource.name(), "r2"); assert_eq!(resource.name(), "r2");
} }
} }