From 4731a5124efddd05529a566dd1b3da3f526a97b1 Mon Sep 17 00:00:00 2001 From: Daniel Eggert Date: Fri, 25 Apr 2025 09:51:34 +0200 Subject: [PATCH 1/3] Revert RegexBuilder workaround --- Sources/FoundationEssentials/URL/URLTemplate.swift | 3 +-- .../FoundationEssentials/URL/URLTemplate_Expression.swift | 5 ----- .../URL/URLTemplate_PercentEncoding.swift | 2 -- .../URITemplatingTests/URLTemplate_ExpressionTests.swift | 2 -- .../URITemplatingTests/URLTemplate_TemplateTests.swift | 2 -- 5 files changed, 1 insertion(+), 13 deletions(-) diff --git a/Sources/FoundationEssentials/URL/URLTemplate.swift b/Sources/FoundationEssentials/URL/URLTemplate.swift index 8987579e0..cc72abef8 100644 --- a/Sources/FoundationEssentials/URL/URLTemplate.swift +++ b/Sources/FoundationEssentials/URL/URLTemplate.swift @@ -130,7 +130,7 @@ extension URL { } // MARK: - Parse -#if FOUNDATION_FRAMEWORK + extension URL.Template { /// Creates a new template from its text form. /// @@ -164,7 +164,6 @@ extension URL.Template { } } } -#endif // MARK: - diff --git a/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift b/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift index 6e7a0fbc9..b46f9559c 100644 --- a/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift +++ b/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift @@ -10,10 +10,7 @@ // //===----------------------------------------------------------------------===// -#if FOUNDATION_FRAMEWORK internal import RegexBuilder -#endif - #if canImport(CollectionsInternal) internal import CollectionsInternal #elseif canImport(OrderedCollections) @@ -82,7 +79,6 @@ extension URL.Template.Expression.Element: CustomStringConvertible { } } -#if FOUNDATION_FRAMEWORK extension URL.Template.Expression { init(_ input: String) throws { var remainder = input[...] @@ -206,7 +202,6 @@ extension URL.Template { } } } -#endif // .------------------------------------------------------------------. // | NUL + . / ; ? & # | diff --git a/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift b/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift index 79f39cb58..93bb6ecf3 100644 --- a/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift +++ b/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift @@ -10,9 +10,7 @@ // //===----------------------------------------------------------------------===// -#if FOUNDATION_FRAMEWORK internal import RegexBuilder -#endif extension String { /// Convert to NFC and percent-escape. diff --git a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift index 2a98f9593..fb17c4fb9 100644 --- a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift +++ b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift @@ -20,7 +20,6 @@ import struct Foundation.URL #endif import Testing -#if FOUNDATION_FRAMEWORK @Suite("URL.Template Expression") private enum ExpressionTests { private typealias Expression = URL.Template.Expression @@ -277,4 +276,3 @@ private enum ExpressionTests { #expect((try? Expression(input)) == nil, "Should fail to parse, but not crash.") } } -#endif diff --git a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_TemplateTests.swift b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_TemplateTests.swift index ec0cc4865..9089a32d9 100644 --- a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_TemplateTests.swift +++ b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_TemplateTests.swift @@ -54,7 +54,6 @@ private var variables: [URL.Template.VariableName: URL.Template.Value] { ] } -#if FOUNDATION_FRAMEWORK private func assertReplacing(template: String, result: String, sourceLocation: SourceLocation = #_sourceLocation) { do { let t = try #require(URL.Template(template)) @@ -264,4 +263,3 @@ private enum TemplateTests { assertReplacing(template: "{&keys*}", result: "&semi=%3B&dot=.&comma=%2C") } } -#endif From e885e96a14445b85a6a6aeff6b3f2606332859d7 Mon Sep 17 00:00:00 2001 From: Daniel Eggert Date: Fri, 25 Apr 2025 09:51:47 +0200 Subject: [PATCH 2/3] Cleanup private --- .../URITemplatingTests/URLTemplate_ExpressionTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift index fb17c4fb9..111bcd715 100644 --- a/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift +++ b/Tests/FoundationEssentialsTests/URITemplatingTests/URLTemplate_ExpressionTests.swift @@ -22,8 +22,8 @@ import Testing @Suite("URL.Template Expression") private enum ExpressionTests { - private typealias Expression = URL.Template.Expression - private typealias Element = URL.Template.Expression.Element + typealias Expression = URL.Template.Expression + typealias Element = URL.Template.Expression.Element @Test static func parsingWithSingleName() throws { From 203c480291e83f58290d78f0c03fcfb7465418f9 Mon Sep 17 00:00:00 2001 From: Daniel Eggert Date: Fri, 25 Apr 2025 10:27:03 +0200 Subject: [PATCH 3/3] Move off of RegexBuilder --- .../URL/URLTemplate_Expression.swift | 49 +++---------------- .../URL/URLTemplate_PercentEncoding.swift | 2 - 2 files changed, 7 insertions(+), 44 deletions(-) diff --git a/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift b/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift index b46f9559c..e368f354d 100644 --- a/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift +++ b/Sources/FoundationEssentials/URL/URLTemplate_Expression.swift @@ -10,7 +10,6 @@ // //===----------------------------------------------------------------------===// -internal import RegexBuilder #if canImport(CollectionsInternal) internal import CollectionsInternal #elseif canImport(OrderedCollections) @@ -104,7 +103,7 @@ extension URL.Template.Expression { let explode: Bool if let max = match.output.3 { guard - let m = max.map({ Int($0) }) + let m = Int(max) else { throw URL.Template.InvalidExpression(text: "Invalid maximum length '\(input[match.range])'") } maximumLength = m explode = false @@ -148,57 +147,23 @@ extension URL.Template { let operatorRegex: Regex<(Substring, Substring?)> let separatorRegex: Regex<(Substring)> - let elementRegex: Regex<(Substring, Substring, Substring?, Substring??)> - let uriTemplateRegex: Regex.RegexOutput>.RegexOutput)>.RegexOutput> + let elementRegex: Regex<(Substring, Substring, Substring?, Substring?)> + let uriTemplateRegex: Regex<(Substring, Substring)> private init() { - self.operatorRegex = Regex { - Optionally { - Capture { - One(.anyOf("+#./;?&")) - } - } - } + self.operatorRegex = try! Regex(#"([\+#.\/;\?&])?"#) .asciiOnlyWordCharacters() .asciiOnlyDigits() .asciiOnlyCharacterClasses() - self.separatorRegex = Regex { - "," - } + self.separatorRegex = try! Regex(#","#) .asciiOnlyWordCharacters() .asciiOnlyDigits() .asciiOnlyCharacterClasses() - self.elementRegex = Regex { - Capture { - One(("a"..."z").union("A"..."Z")) - ZeroOrMore(("a"..."z").union("A"..."Z").union("0"..."9").union(.anyOf("_"))) - } - Optionally { - Capture { - ChoiceOf { - Regex { - ":" - Capture { - ZeroOrMore(.digit) - } - } - "*" - } - } - } - } + self.elementRegex = try! Regex(#"([a-zA-Z][a-zA-Z0-9_]*)(:([0-9]*)|\*)?"#) .asciiOnlyWordCharacters() .asciiOnlyDigits() .asciiOnlyCharacterClasses() - self.uriTemplateRegex = Regex { - "{" - Capture { - OneOrMore { - CharacterClass.any.subtracting(.anyOf("}")) - } - } - "}" - } + self.uriTemplateRegex = try! Regex(#"{([^}]+)}"#) } } } diff --git a/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift b/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift index 93bb6ecf3..6b1a760fe 100644 --- a/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift +++ b/Sources/FoundationEssentials/URL/URLTemplate_PercentEncoding.swift @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -internal import RegexBuilder - extension String { /// Convert to NFC and percent-escape. func normalizedAddingPercentEncoding(