store Cow in actix-router Path

This commit is contained in:
ibraheemdev 2021-04-19 09:41:23 -04:00
parent 978e4f25fb
commit 7b365dc657
2 changed files with 48 additions and 26 deletions

View File

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::ops::Index;
use serde::de;
@ -5,12 +6,18 @@ use serde::de;
use crate::de::PathDeserializer;
use crate::{Resource, ResourcePath};
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone)]
pub(crate) enum PathItem {
Static(&'static str),
Static(Cow<'static, str>),
Segment(u16, u16),
}
impl Default for PathItem {
fn default() -> Self {
Self::Static(Cow::Borrowed(""))
}
}
/// Resource path match information
///
/// If resource path contains variable patterns, `Path` stores them.
@ -18,7 +25,7 @@ pub(crate) enum PathItem {
pub struct Path<T> {
path: T,
pub(crate) skip: u16,
pub(crate) segments: Vec<(&'static str, PathItem)>,
pub(crate) segments: Vec<(Cow<'static, str>, PathItem)>,
}
impl<T: Default> Default for Path<T> {
@ -95,18 +102,24 @@ impl<T: ResourcePath> Path<T> {
self.skip += n;
}
pub(crate) fn add(&mut self, name: &'static str, value: PathItem) {
pub(crate) fn add(&mut self, name: impl Into<Cow<'static, str>>, value: PathItem) {
match value {
PathItem::Static(s) => self.segments.push((name, PathItem::Static(s))),
PathItem::Segment(begin, end) => self
.segments
.push((name, PathItem::Segment(self.skip + begin, self.skip + end))),
PathItem::Static(s) => self.segments.push((name.into(), PathItem::Static(s))),
PathItem::Segment(begin, end) => self.segments.push((
name.into(),
PathItem::Segment(self.skip + begin, self.skip + end),
)),
}
}
#[doc(hidden)]
pub fn add_static(&mut self, name: &'static str, value: &'static str) {
self.segments.push((name, PathItem::Static(value)));
pub fn add_static(
&mut self,
name: impl Into<Cow<'static, str>>,
value: impl Into<Cow<'static, str>>,
) {
let value: Cow<'static, str> = value.into();
self.segments.push((name.into(), PathItem::Static(value)));
}
/// Check if there are any matched patterns

View File

@ -1,3 +1,4 @@
use std::array::IntoIter;
use std::cmp::min;
use std::collections::HashMap;
use std::hash::{Hash, Hasher};
@ -274,8 +275,7 @@ impl ResourceDef {
PatternType::Dynamic(ref re, ref names, len) => {
let mut idx = 0;
let mut pos = 0;
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
if let Some(captures) = re.captures(path.path()) {
for (no, name) in names.iter().enumerate() {
@ -294,8 +294,11 @@ impl ResourceDef {
} else {
return false;
}
for idx in 0..idx {
path.add(names[idx], segments[idx]);
for (idx, segment) in IntoIter::new(segments)
.enumerate()
.take_while(|(i, _)| *i != idx)
{
path.add(names[idx], segment);
}
path.skip((pos + len) as u16);
true
@ -305,8 +308,7 @@ impl ResourceDef {
let (ref pattern, ref names, len) = params[idx];
let mut idx = 0;
let mut pos = 0;
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
if let Some(captures) = pattern.captures(path.path()) {
for (no, name) in names.iter().enumerate() {
@ -326,8 +328,11 @@ impl ResourceDef {
} else {
return false;
}
for idx in 0..idx {
path.add(names[idx], segments[idx]);
for (idx, segment) in IntoIter::new(segments)
.enumerate()
.take_while(|(i, _)| *i != idx)
{
path.add(names[idx], segment);
}
path.skip((pos + len) as u16);
true
@ -387,8 +392,7 @@ impl ResourceDef {
PatternType::Dynamic(ref re, ref names, len) => {
let mut idx = 0;
let mut pos = 0;
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
if let Some(captures) = re.captures(res.resource_path().path()) {
for (no, name) in names.iter().enumerate() {
@ -413,8 +417,11 @@ impl ResourceDef {
}
let path = res.resource_path();
for idx in 0..idx {
path.add(names[idx], segments[idx]);
for (idx, segment) in IntoIter::new(segments)
.enumerate()
.take_while(|(i, _)| *i != idx)
{
path.add(names[idx], segment);
}
path.skip((pos + len) as u16);
true
@ -425,8 +432,7 @@ impl ResourceDef {
let (ref pattern, ref names, len) = params[idx];
let mut idx = 0;
let mut pos = 0;
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] =
[PathItem::Static(""); MAX_DYNAMIC_SEGMENTS];
let mut segments: [PathItem; MAX_DYNAMIC_SEGMENTS] = Default::default();
if let Some(captures) = pattern.captures(path) {
for (no, name) in names.iter().enumerate() {
@ -452,8 +458,11 @@ impl ResourceDef {
}
let path = res.resource_path();
for idx in 0..idx {
path.add(names[idx], segments[idx]);
for (idx, segment) in IntoIter::new(segments)
.enumerate()
.take_while(|(i, _)| *i != idx)
{
path.add(names[idx], segment);
}
path.skip((pos + len) as u16);
true