From 42bad8371f0070b4a8abbb2d3c31ed1029e446d0 Mon Sep 17 00:00:00 2001 From: Mark Date: Sun, 4 May 2025 10:17:09 -0700 Subject: [PATCH] Simplify regex --- src/manifest/rule.rs | 62 +++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/manifest/rule.rs b/src/manifest/rule.rs index 2f73011..b2b87cc 100644 --- a/src/manifest/rule.rs +++ b/src/manifest/rule.rs @@ -25,34 +25,26 @@ impl RegexSegment { // Neighboring doublestar is always responsible for slashes (_, Self::Single(x), Some(Self::DoubleStar)) => x.to_owned(), - // [^/]+ is a "segment" (a block of non-slash chars) - // The "base" doublestar pattern is a segment - // followed by zero or more segments prefixed by a slash. - // // No additional slashes - (None, Self::DoubleStar, None) => "((?:[^/]+(?:[/][^/]+)*)?)".into(), + (None, Self::DoubleStar, None) => "((?:.*)?)".into(), + + // Leading slash + (Some(Self::Single(_)), Self::DoubleStar, None) => "((?:[/].*)?)".into(), + + // Trailing slash + (None, Self::DoubleStar, Some(Self::Single(_))) => "((?:.*[/])?)".into(), + + // Leading and trailing slash. + // Also, replace self with a [/] when empty. + (Some(Self::Single(_)), Self::DoubleStar, Some(Self::Single(_))) => { + "((?:[/].*[/])|[/])".into() + } // Doublestars cannot be neighbors (_, Self::DoubleStar, Some(Self::DoubleStar)) | (Some(Self::DoubleStar), Self::DoubleStar, _) => { unreachable!("consecutive doublestars must be reduced") } - - // Leading slash - (Some(Self::Single(_)), Self::DoubleStar, None) => { - "((?:[/][^/]+(?:[/][^/]+)*)?)".into() - } - - // Trailing slash - (None, Self::DoubleStar, Some(Self::Single(_))) => { - "((?:[^/]+(?:[/][^/]+)*[/])?)".into() - } - - // Leading and trailing slash. - // Also, replace self with a [/] when empty. - (Some(Self::Single(_)), Self::DoubleStar, Some(Self::Single(_))) => { - "((?:[/][^/]+(?:[/][^/]+)*[/])|[/])".into() - } } } } @@ -301,6 +293,34 @@ mod tests { assert!(!regex.is_match("root/testfile")); assert!(!regex.is_match("root/testxxfile")); } + + #[test] + fn doublestar_nullable() { + let regex = rule_regex(&["root/**/file"]); + + assert!(regex.is_match("root/test/file")); + assert!(regex.is_match("root/file")); + assert!(!regex.is_match("rootfile")); + } + + #[test] + fn doublestar_nullable_post() { + let regex = rule_regex(&["root/**"]); + + assert!(regex.is_match("root")); + assert!(regex.is_match("root/file")); + assert!(!regex.is_match("rootfile")); + } + + #[test] + fn doublestar_nullable_pre() { + let regex = rule_regex(&["**/file"]); + + assert!(regex.is_match("file")); + assert!(regex.is_match("root/file")); + assert!(!regex.is_match("rootfile")); + } + #[test] fn doublestar_bad_extension() { let regex = rule_regex(&["**.flac"]);