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:
parent
ff0ab733e4
commit
a5369aed8b
@ -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) {
|
||||||
|
11
src/param.rs
11
src/param.rs
@ -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) => {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user