Skip to content

Commit 511d216

Browse files
author
Tim Vermeulen
committed
Add _MatchResult and allow RegexProtocol in algorithms
1 parent d549b4e commit 511d216

16 files changed

+166
-129
lines changed

Sources/_StringProcessing/Algorithms/Algorithms/Contains.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ extension BidirectionalCollection where Element: Comparable {
4040
// MARK: Regex algorithms
4141

4242
extension BidirectionalCollection where SubSequence == Substring {
43-
public func contains<Capture>(_ regex: Regex<Capture>) -> Bool {
43+
public func contains<R: RegexProtocol>(_ regex: R) -> Bool {
4444
contains(RegexConsumer(regex))
4545
}
4646
}

Sources/_StringProcessing/Algorithms/Algorithms/FirstRange.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,11 @@ extension BidirectionalCollection where Element: Comparable {
5656
// MARK: Regex algorithms
5757

5858
extension BidirectionalCollection where SubSequence == Substring {
59-
public func firstRange<Capture>(of regex: Regex<Capture>) -> Range<Index>? {
59+
public func firstRange<R: RegexProtocol>(of regex: R) -> Range<Index>? {
6060
firstRange(of: RegexConsumer(regex))
6161
}
6262

63-
public func lastRange<Capture>(of regex: Regex<Capture>) -> Range<Index>? {
63+
public func lastRange<R: RegexProtocol>(of regex: R) -> Range<Index>? {
6464
lastRange(of: RegexConsumer(regex))
6565
}
6666
}

Sources/_StringProcessing/Algorithms/Algorithms/Ranges.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,15 +216,15 @@ extension BidirectionalCollection where Element: Comparable {
216216
// MARK: Regex algorithms
217217

218218
extension BidirectionalCollection where SubSequence == Substring {
219-
public func ranges<Capture>(
220-
of regex: Regex<Capture>
221-
) -> RangesCollection<RegexConsumer<Self, Capture>> {
219+
public func ranges<R: RegexProtocol>(
220+
of regex: R
221+
) -> RangesCollection<RegexConsumer<R, Self>> {
222222
ranges(of: RegexConsumer(regex))
223223
}
224224

225-
public func rangesFromBack<Capture>(
226-
of regex: Regex<Capture>
227-
) -> ReversedRangesCollection<RegexConsumer<Self, Capture>> {
225+
public func rangesFromBack<R: RegexProtocol>(
226+
of regex: R
227+
) -> ReversedRangesCollection<RegexConsumer<R, Self>> {
228228
rangesFromBack(of: RegexConsumer(regex))
229229
}
230230
}

Sources/_StringProcessing/Algorithms/Algorithms/Replace.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ extension RangeReplaceableCollection
149149
// MARK: Regex algorithms
150150

151151
extension RangeReplaceableCollection where SubSequence == Substring {
152-
public func replacing<Capture, Replacement: Collection>(
153-
_ regex: Regex<Capture>,
152+
public func replacing<R: RegexProtocol, Replacement: Collection>(
153+
_ regex: R,
154154
with replacement: Replacement,
155155
subrange: Range<Index>,
156156
maxReplacements: Int = .max
@@ -162,8 +162,8 @@ extension RangeReplaceableCollection where SubSequence == Substring {
162162
maxReplacements: maxReplacements)
163163
}
164164

165-
public func replacing<Capture, Replacement: Collection>(
166-
_ regex: Regex<Capture>,
165+
public func replacing<R: RegexProtocol, Replacement: Collection>(
166+
_ regex: R,
167167
with replacement: Replacement,
168168
maxReplacements: Int = .max
169169
) -> Self where Replacement.Element == Element {
@@ -174,8 +174,8 @@ extension RangeReplaceableCollection where SubSequence == Substring {
174174
maxReplacements: maxReplacements)
175175
}
176176

177-
public mutating func replace<Capture, Replacement: Collection>(
178-
_ regex: Regex<Capture>,
177+
public mutating func replace<R: RegexProtocol, Replacement: Collection>(
178+
_ regex: R,
179179
with replacement: Replacement,
180180
maxReplacements: Int = .max
181181
) where Replacement.Element == Element {

Sources/_StringProcessing/Algorithms/Algorithms/Split.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,15 @@ extension BidirectionalCollection where Element: Comparable {
275275
// MARK: Regex algorithms
276276

277277
extension BidirectionalCollection where SubSequence == Substring {
278-
public func split<Capture>(
279-
by separator: Regex<Capture>
280-
) -> SplitCollection<RegexConsumer<Self, Capture>> {
278+
public func split<R: RegexProtocol>(
279+
by separator: R
280+
) -> SplitCollection<RegexConsumer<R, Self>> {
281281
split(by: RegexConsumer(separator))
282282
}
283283

284-
public func splitFromBack<Capture>(
285-
by separator: Regex<Capture>
286-
) -> ReversedSplitCollection<RegexConsumer<Self, Capture>> {
284+
public func splitFromBack<R: RegexProtocol>(
285+
by separator: R
286+
) -> ReversedSplitCollection<RegexConsumer<R, Self>> {
287287
splitFromBack(by: RegexConsumer(separator))
288288
}
289289
}

Sources/_StringProcessing/Algorithms/Algorithms/StartsWith.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ extension BidirectionalCollection where Element: Equatable {
4848
// MARK: Regex algorithms
4949

5050
extension BidirectionalCollection where SubSequence == Substring {
51-
public func starts<Capture>(with regex: Regex<Capture>) -> Bool {
51+
public func starts<R: RegexProtocol>(with regex: R) -> Bool {
5252
starts(with: RegexConsumer(regex))
5353
}
5454

55-
public func ends<Capture>(with regex: Regex<Capture>) -> Bool {
55+
public func ends<R: RegexProtocol>(with regex: R) -> Bool {
5656
ends(with: RegexConsumer(regex))
5757
}
5858
}

Sources/_StringProcessing/Algorithms/Algorithms/Trim.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -257,48 +257,48 @@ extension RangeReplaceableCollection
257257
// MARK: Regex algorithms
258258

259259
extension BidirectionalCollection where SubSequence == Substring {
260-
public func trimmingPrefix<Capture>(_ regex: Regex<Capture>) -> SubSequence {
260+
public func trimmingPrefix<R: RegexProtocol>(_ regex: R) -> SubSequence {
261261
trimmingPrefix(RegexConsumer(regex))
262262
}
263263

264-
public func trimmingSuffix<Capture>(_ regex: Regex<Capture>) -> SubSequence {
264+
public func trimmingSuffix<R: RegexProtocol>(_ regex: R) -> SubSequence {
265265
trimmingSuffix(RegexConsumer(regex))
266266
}
267267

268-
public func trimming<Capture>(_ regex: Regex<Capture>) -> SubSequence {
268+
public func trimming<R: RegexProtocol>(_ regex: R) -> SubSequence {
269269
trimming(RegexConsumer(regex))
270270
}
271271
}
272272

273273
extension RangeReplaceableCollection
274274
where Self: BidirectionalCollection, SubSequence == Substring
275275
{
276-
public mutating func trimPrefix<Capture>(_ regex: Regex<Capture>) {
276+
public mutating func trimPrefix<R: RegexProtocol>(_ regex: R) {
277277
trimPrefix(RegexConsumer(regex))
278278
}
279279

280-
public mutating func trimSuffix<Capture>(_ regex: Regex<Capture>) {
280+
public mutating func trimSuffix<R: RegexProtocol>(_ regex: R) {
281281
trimSuffix(RegexConsumer(regex))
282282
}
283283

284-
public mutating func trim<Capture>(_ regex: Regex<Capture>) {
285-
let consumer = RegexConsumer<Self, Capture>(regex)
284+
public mutating func trim<R: RegexProtocol>(_ regex: R) {
285+
let consumer = RegexConsumer<R, Self>(regex)
286286
trimPrefix(consumer)
287287
trimSuffix(consumer)
288288
}
289289
}
290290

291291
extension Substring {
292-
public mutating func trimPrefix<Capture>(_ regex: Regex<Capture>) {
292+
public mutating func trimPrefix<R: RegexProtocol>(_ regex: R) {
293293
trimPrefix(RegexConsumer(regex))
294294
}
295295

296-
public mutating func trimSuffix<Capture>(_ regex: Regex<Capture>) {
296+
public mutating func trimSuffix<R: RegexProtocol>(_ regex: R) {
297297
trimSuffix(RegexConsumer(regex))
298298
}
299299

300-
public mutating func trim<Capture>(_ regex: Regex<Capture>) {
301-
let consumer = RegexConsumer<Self, Capture>(regex)
300+
public mutating func trim<R: RegexProtocol>(_ regex: R) {
301+
let consumer = RegexConsumer<R, Self>(regex)
302302
trimPrefix(consumer)
303303
trimSuffix(consumer)
304304
}

Sources/_StringProcessing/Algorithms/Consumers/RegexConsumer.swift

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,35 +10,37 @@
1010
//===----------------------------------------------------------------------===//
1111

1212
public struct RegexConsumer<
13-
Consumed: BidirectionalCollection, Capture: MatchProtocol
13+
R: RegexProtocol, Consumed: BidirectionalCollection
1414
> where Consumed.SubSequence == Substring {
1515
// TODO: Should `Regex` itself implement these protocols?
16-
let regex: Regex<Capture>
16+
let regex: R
1717

18-
public init(_ regex: Regex<Capture>) {
18+
public init(_ regex: R) {
1919
self.regex = regex
2020
}
21-
21+
}
22+
23+
extension RegexConsumer {
2224
func _matchingConsuming(
2325
_ consumed: Substring, in range: Range<String.Index>
24-
) -> (Capture, String.Index)? {
26+
) -> (upperBound: String.Index, match: Match)? {
2527
guard let result = regex._match(
2628
consumed.base,
2729
in: range, mode: .partialFromFront
2830
) else { return nil }
29-
return (result.match, result.range.upperBound)
31+
return (result.range.upperBound, result.match)
3032
}
3133
}
3234

3335
// TODO: Explicitly implement the non-matching consumer/searcher protocols as
3436
// well, taking advantage of the fact that the captures can be ignored
3537

3638
extension RegexConsumer: MatchingCollectionConsumer {
37-
public typealias Match = Capture
39+
public typealias Match = R.Match
3840

3941
public func matchingConsuming(
4042
_ consumed: Consumed, in range: Range<Consumed.Index>
41-
) -> (Capture, String.Index)? {
43+
) -> (upperBound: String.Index, match: Match)? {
4244
_matchingConsuming(consumed[...], in: range)
4345
}
4446
}
@@ -47,14 +49,14 @@ extension RegexConsumer: MatchingCollectionConsumer {
4749
extension RegexConsumer: BidirectionalMatchingCollectionConsumer {
4850
public func matchingConsumingBack(
4951
_ consumed: Consumed, in range: Range<Consumed.Index>
50-
) -> (Capture, String.Index)? {
52+
) -> (lowerBound: String.Index, match: Match)? {
5153
var i = range.lowerBound
5254
while true {
53-
if let (capture, end) = _matchingConsuming(
55+
if let (end, capture) = _matchingConsuming(
5456
consumed[...],
5557
in: i..<range.upperBound
5658
), end == range.upperBound {
57-
return (capture, i)
59+
return (i, capture)
5860
} else if i == range.upperBound {
5961
return nil
6062
} else {
@@ -72,7 +74,7 @@ extension RegexConsumer: MatchingStatelessCollectionSearcher {
7274
// its own internal state
7375
public func matchingSearch(
7476
_ searched: Searched, in range: Range<Searched.Index>
75-
) -> (Capture, Range<String.Index>)? {
77+
) -> (range: Range<String.Index>, match: Match)? {
7678
ConsumerSearcher(consumer: self).matchingSearch(searched, in: range)
7779
}
7880
}
@@ -83,7 +85,7 @@ extension RegexConsumer: BackwardMatchingStatelessCollectionSearcher {
8385

8486
public func matchingSearchBack(
8587
_ searched: BackwardSearched, in range: Range<Searched.Index>
86-
) -> (Capture, Range<String.Index>)? {
88+
) -> (range: Range<String.Index>, match: Match)? {
8789
ConsumerSearcher(consumer: self).matchingSearchBack(searched, in: range)
8890
}
8991
}

Sources/_StringProcessing/Algorithms/Matching/FirstMatch.swift

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,39 @@
1414
extension Collection {
1515
public func firstMatch<S: MatchingCollectionSearcher>(
1616
of searcher: S
17-
) -> (S.Match, Range<S.Searched.Index>)? where S.Searched == Self {
17+
) -> _MatchResult<S>? where S.Searched == Self {
1818
var state = searcher.state(for: self, in: startIndex..<endIndex)
19-
return searcher.matchingSearch(self, &state)
19+
return searcher.matchingSearch(self, &state).map { range, result in
20+
_MatchResult(match: self[range], result: result)
21+
}
2022
}
2123
}
2224

2325
extension BidirectionalCollection {
2426
public func lastMatch<S: BackwardMatchingCollectionSearcher>(
2527
of searcher: S
26-
) -> (S.Match, Range<S.BackwardSearched.Index>)?
28+
) -> _BackwardMatchResult<S>?
2729
where S.BackwardSearched == Self
2830
{
2931
var state = searcher.backwardState(for: self, in: startIndex..<endIndex)
30-
return searcher.matchingSearchBack(self, &state)
32+
return searcher.matchingSearchBack(self, &state).map { range, result in
33+
_BackwardMatchResult(match: self[range], result: result)
34+
}
3135
}
3236
}
3337

3438
// MARK: Regex algorithms
3539

3640
extension BidirectionalCollection where SubSequence == Substring {
37-
public func firstMatch<Capture>(
38-
of regex: Regex<Capture>
39-
) -> (Capture, Range<String.Index>)? {
41+
public func firstMatch<R: RegexProtocol>(
42+
of regex: R
43+
) -> _MatchResult<RegexConsumer<R, Self>>? {
4044
firstMatch(of: RegexConsumer(regex))
4145
}
4246

43-
public func lastMatch<Capture>(
44-
of regex: Regex<Capture>
45-
) -> (Capture, Range<String.Index>)? {
47+
public func lastMatch<R: RegexProtocol>(
48+
of regex: R
49+
) -> _BackwardMatchResult<RegexConsumer<R, Self>>? {
4650
lastMatch(of: RegexConsumer(regex))
4751
}
4852
}

0 commit comments

Comments
 (0)