Skip to content

Commit 6f4d222

Browse files
authored
store Cow in actix-router Path (#345)
1 parent 54b22f9 commit 6f4d222

File tree

3 files changed

+38
-35
lines changed

3 files changed

+38
-35
lines changed

actix-router/CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55

66
## 0.2.7 - 2021-02-06
77
* Add `Router::recognize_checked` [#247]
8+
* `Path::add` and `add_static` takes `impl Into<Cow<'static, str>>` [#345]
89

910
[#247]: https://github.com/actix/actix-net/pull/247
10-
11+
[#345]: https://github.com/actix/actix-net/pull/345
1112

1213
## 0.2.6 - 2021-01-09
1314
* Use `bytestring` version range compatible with Bytes v1.0. [#246]

actix-router/src/path.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,31 @@
1+
use std::borrow::Cow;
12
use std::ops::Index;
23

34
use serde::de;
45

56
use crate::de::PathDeserializer;
67
use crate::{Resource, ResourcePath};
78

8-
#[derive(Debug, Clone, Copy)]
9+
#[derive(Debug, Clone)]
910
pub(crate) enum PathItem {
10-
Static(&'static str),
11+
Static(Cow<'static, str>),
1112
Segment(u16, u16),
1213
}
1314

15+
impl Default for PathItem {
16+
fn default() -> Self {
17+
Self::Static(Cow::Borrowed(""))
18+
}
19+
}
20+
1421
/// Resource path match information
1522
///
1623
/// If resource path contains variable patterns, `Path` stores them.
1724
#[derive(Debug)]
1825
pub struct Path<T> {
1926
path: T,
2027
pub(crate) skip: u16,
21-
pub(crate) segments: Vec<(&'static str, PathItem)>,
28+
pub(crate) segments: Vec<(Cow<'static, str>, PathItem)>,
2229
}
2330

2431
impl<T: Default> Default for Path<T> {
@@ -95,18 +102,24 @@ impl<T: ResourcePath> Path<T> {
95102
self.skip += n;
96103
}
97104

98-
pub(crate) fn add(&mut self, name: &'static str, value: PathItem) {
105+
pub(crate) fn add(&mut self, name: impl Into<Cow<'static, str>>, value: PathItem) {
99106
match value {
100-
PathItem::Static(s) => self.segments.push((name, PathItem::Static(s))),
101-
PathItem::Segment(begin, end) => self
102-
.segments
103-
.push((name, PathItem::Segment(self.skip + begin, self.skip + end))),
107+
PathItem::Static(s) => self.segments.push((name.into(), PathItem::Static(s))),
108+
PathItem::Segment(begin, end) => self.segments.push((
109+
name.into(),
110+
PathItem::Segment(self.skip + begin, self.skip + end),
111+
)),
104112
}
105113
}
106114

107115
#[doc(hidden)]
108-
pub fn add_static(&mut self, name: &'static str, value: &'static str) {
109-
self.segments.push((name, PathItem::Static(value)));
116+
pub fn add_static(
117+
&mut self,
118+
name: impl Into<Cow<'static, str>>,
119+
value: impl Into<Cow<'static, str>>,
120+
) {
121+
self.segments
122+
.push((name.into(), PathItem::Static(value.into())));
110123
}
111124

112125
/// Check if there are any matched patterns

actix-router/src/resource.rs

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::cmp::min;
22
use std::collections::HashMap;
33
use std::hash::{Hash, Hasher};
4+
use std::mem;
45

56
use regex::{escape, Regex, RegexSet};
67

@@ -272,15 +273,12 @@ impl ResourceDef {
272273
true
273274
}
274275
PatternType::Dynamic(ref re, ref names, len) => {
275-
let mut idx = 0;
276276
let mut pos = 0;
277-
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
278-
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
277+
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
279278

280279
if let Some(captures) = re.captures(path.path()) {
281280
for (no, name) in names.iter().enumerate() {
282281
if let Some(m) = captures.name(&name) {
283-
idx += 1;
284282
pos = m.end();
285283
segments[no] = PathItem::Segment(m.start() as u16, m.end() as u16);
286284
} else {
@@ -294,24 +292,21 @@ impl ResourceDef {
294292
} else {
295293
return false;
296294
}
297-
for idx in 0..idx {
298-
path.add(names[idx], segments[idx]);
295+
for i in 0..names.len() {
296+
path.add(names[i], mem::take(&mut segments[i]));
299297
}
300298
path.skip((pos + len) as u16);
301299
true
302300
}
303301
PatternType::DynamicSet(ref re, ref params) => {
304302
if let Some(idx) = re.matches(path.path()).into_iter().next() {
305303
let (ref pattern, ref names, len) = params[idx];
306-
let mut idx = 0;
307304
let mut pos = 0;
308-
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
309-
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
305+
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
310306

311307
if let Some(captures) = pattern.captures(path.path()) {
312308
for (no, name) in names.iter().enumerate() {
313309
if let Some(m) = captures.name(&name) {
314-
idx += 1;
315310
pos = m.end();
316311
segments[no] =
317312
PathItem::Segment(m.start() as u16, m.end() as u16);
@@ -326,8 +321,8 @@ impl ResourceDef {
326321
} else {
327322
return false;
328323
}
329-
for idx in 0..idx {
330-
path.add(names[idx], segments[idx]);
324+
for i in 0..names.len() {
325+
path.add(names[i], mem::take(&mut segments[i]));
331326
}
332327
path.skip((pos + len) as u16);
333328
true
@@ -385,15 +380,12 @@ impl ResourceDef {
385380
true
386381
}
387382
PatternType::Dynamic(ref re, ref names, len) => {
388-
let mut idx = 0;
389383
let mut pos = 0;
390-
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
391-
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
384+
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
392385

393386
if let Some(captures) = re.captures(res.resource_path().path()) {
394387
for (no, name) in names.iter().enumerate() {
395388
if let Some(m) = captures.name(&name) {
396-
idx += 1;
397389
pos = m.end();
398390
segments[no] = PathItem::Segment(m.start() as u16, m.end() as u16);
399391
} else {
@@ -413,8 +405,8 @@ impl ResourceDef {
413405
}
414406

415407
let path = res.resource_path();
416-
for idx in 0..idx {
417-
path.add(names[idx], segments[idx]);
408+
for i in 0..names.len() {
409+
path.add(names[i], mem::take(&mut segments[i]));
418410
}
419411
path.skip((pos + len) as u16);
420412
true
@@ -423,15 +415,12 @@ impl ResourceDef {
423415
let path = res.resource_path().path();
424416
if let Some(idx) = re.matches(path).into_iter().next() {
425417
let (ref pattern, ref names, len) = params[idx];
426-
let mut idx = 0;
427418
let mut pos = 0;
428-
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
429-
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
419+
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
430420

431421
if let Some(captures) = pattern.captures(path) {
432422
for (no, name) in names.iter().enumerate() {
433423
if let Some(m) = captures.name(&name) {
434-
idx += 1;
435424
pos = m.end();
436425
segments[no] =
437426
PathItem::Segment(m.start() as u16, m.end() as u16);
@@ -452,8 +441,8 @@ impl ResourceDef {
452441
}
453442

454443
let path = res.resource_path();
455-
for idx in 0..idx {
456-
path.add(names[idx], segments[idx]);
444+
for i in 0..names.len() {
445+
path.add(names[i], mem::take(&mut segments[i]));
457446
}
458447
path.skip((pos + len) as u16);
459448
true

0 commit comments

Comments
 (0)