prevent trailing const("") elements

This commit is contained in:
Rob Ede 2021-07-16 20:42:06 +01:00
parent ad4ed667fe
commit 78b2861108
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
1 changed files with 28 additions and 19 deletions

View File

@ -506,28 +506,31 @@ impl ResourceDef {
} }
fn parse( fn parse(
mut pattern: &str, pattern: &str,
for_prefix: bool, for_prefix: bool,
force_dynamic: bool, force_dynamic: bool,
) -> (PatternType, Vec<PatternElement>) { ) -> (PatternType, Vec<PatternElement>) {
if !force_dynamic && pattern.find('{').is_none() && !pattern.ends_with('*') { let mut unprocessed = pattern;
if !force_dynamic && unprocessed.find('{').is_none() && !unprocessed.ends_with('*') {
// pattern is static
let tp = if for_prefix { let tp = if for_prefix {
PatternType::Prefix(pattern.to_owned()) PatternType::Prefix(unprocessed.to_owned())
} else { } else {
PatternType::Static(pattern.to_owned()) PatternType::Static(unprocessed.to_owned())
}; };
return (tp, vec![PatternElement::Const(pattern.to_owned())]); return (tp, vec![PatternElement::Const(unprocessed.to_owned())]);
} }
let pattern_orig = pattern;
let mut elements = Vec::new(); let mut elements = Vec::new();
let mut re = format!("{}^", REGEX_FLAGS); let mut re = format!("{}^", REGEX_FLAGS);
let mut dyn_elements = 0; let mut dyn_elements = 0;
let mut has_tail_segment = false; let mut has_tail_segment = false;
while let Some(idx) = pattern.find('{') { while let Some(idx) = unprocessed.find('{') {
let (prefix, rem) = pattern.split_at(idx); let (prefix, rem) = unprocessed.split_at(idx);
elements.push(PatternElement::Const(prefix.to_owned())); elements.push(PatternElement::Const(prefix.to_owned()));
re.push_str(&escape(prefix)); re.push_str(&escape(prefix));
@ -541,11 +544,11 @@ impl ResourceDef {
elements.push(param_pattern); elements.push(param_pattern);
re.push_str(&re_part); re.push_str(&re_part);
pattern = rem; unprocessed = rem;
dyn_elements += 1; dyn_elements += 1;
} }
if let Some(path) = pattern.strip_suffix('*') { if let Some(path) = unprocessed.strip_suffix('*') {
// unnamed tail segment // unnamed tail segment
elements.push(PatternElement::Const(path.to_owned())); elements.push(PatternElement::Const(path.to_owned()));
@ -555,11 +558,11 @@ impl ResourceDef {
re.push_str("(.*)"); re.push_str("(.*)");
dyn_elements += 1; dyn_elements += 1;
} else if !has_tail_segment { } else if !has_tail_segment && !unprocessed.is_empty() {
// prevent `Const("")` element from being added after tail segments // prevent `Const("")` element from being added after tail segment
elements.push(PatternElement::Const(pattern.to_owned())); elements.push(PatternElement::Const(unprocessed.to_owned()));
re.push_str(&escape(pattern)); re.push_str(&escape(unprocessed));
} }
if dyn_elements > MAX_DYNAMIC_SEGMENTS { if dyn_elements > MAX_DYNAMIC_SEGMENTS {
@ -575,7 +578,7 @@ impl ResourceDef {
let re = match Regex::new(&re) { let re = match Regex::new(&re) {
Ok(re) => re, Ok(re) => re,
Err(err) => panic!("Wrong path pattern: \"{}\" {}", pattern_orig, err), Err(err) => panic!("Wrong path pattern: \"{}\" {}", pattern, err),
}; };
// `Bok::leak(Box::new(name))` is an intentional memory leak. In typical applications the // `Bok::leak(Box::new(name))` is an intentional memory leak. In typical applications the
@ -872,6 +875,8 @@ mod tests {
#[test] #[test]
fn prefix_static() { fn prefix_static() {
let re = ResourceDef::prefix("/name"); let re = ResourceDef::prefix("/name");
println!("{:#?}", &re);
assert!(re.is_match("/name")); assert!(re.is_match("/name"));
assert!(re.is_match("/name/")); assert!(re.is_match("/name/"));
assert!(re.is_match("/name/test/test")); assert!(re.is_match("/name/test/test"));
@ -909,7 +914,11 @@ mod tests {
#[test] #[test]
fn prefix_dynamic() { fn prefix_dynamic() {
let re = ResourceDef::prefix("/{name}");
println!("{:#?}", &re);
let re = ResourceDef::prefix("/{name}/"); let re = ResourceDef::prefix("/{name}/");
println!("{:#?}", &re);
assert!(re.is_match("/name/")); assert!(re.is_match("/name/"));
assert!(re.is_match("/name/gs")); assert!(re.is_match("/name/gs"));
@ -977,12 +986,12 @@ mod tests {
map.insert("item1", "item"); map.insert("item1", "item");
let mut s = String::new(); let mut s = String::new();
assert!(!resource.resource_path_named(&mut s, &map)); assert!(!resource.resource_path_from_map(&mut s, &map));
map.insert("item2", "item2"); map.insert("item2", "item2");
let mut s = String::new(); let mut s = String::new();
assert!(resource.resource_path_named(&mut s, &map)); assert!(resource.resource_path_from_map(&mut s, &map));
assert_eq!(s, "/user/item/item2/"); assert_eq!(s, "/user/item/item2/");
} }
@ -1000,7 +1009,7 @@ mod tests {
let mut s = String::new(); let mut s = String::new();
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("item1", "item"); map.insert("item1", "item");
assert!(!resource.resource_path_named(&mut s, &map)); assert!(!resource.resource_path_from_map(&mut s, &map));
let mut s = String::new(); let mut s = String::new();
assert!(resource.resource_path_from_map_with_tail(&mut s, &map, "2345")); assert!(resource.resource_path_from_map_with_tail(&mut s, &map, "2345"));
@ -1018,7 +1027,7 @@ mod tests {
let mut s = String::new(); let mut s = String::new();
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert("item1", "item"); map.insert("item1", "item");
assert!(resource.resource_path_named(&mut s, &map)); assert!(resource.resource_path_from_map(&mut s, &map));
assert_eq!(s, "/user/item"); assert_eq!(s, "/user/item");
} }