Skip to content

Commit 3cecdfa

Browse files
committed
Add explicit output type as
1 parent df8d66b commit 3cecdfa

File tree

1 file changed

+74
-68
lines changed

1 file changed

+74
-68
lines changed

Sources/_StringProcessing/Regex/AnyRegexOutput.swift

Lines changed: 74 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,6 @@
1111

1212
@_implementationOnly import _RegexParser
1313

14-
@available(SwiftStdlib 5.7, *)
15-
extension Regex where Output == AnyRegexOutput {
16-
/// Parses and compiles a regular expression, resulting in an existentially-typed capture list.
17-
///
18-
/// - Parameter pattern: The regular expression.
19-
public init(_ pattern: String) throws {
20-
self.init(ast: try parse(pattern, .semantic, .traditional))
21-
}
22-
}
23-
24-
@available(SwiftStdlib 5.7, *)
25-
extension Regex {
26-
/// Parses and compiles a regular expression.
27-
///
28-
/// - Parameter pattern: The regular expression.
29-
/// - Parameter as: The desired type for the output.
30-
public init(
31-
_ pattern: String,
32-
as: Output.Type = Output.self
33-
) throws {
34-
self.init(ast: try parse(pattern, .semantic, .traditional))
35-
}
36-
}
37-
38-
@available(SwiftStdlib 5.7, *)
39-
extension Regex.Match where Output == AnyRegexOutput {
40-
/// Accesses the whole match using the `.0` syntax.
41-
public subscript(
42-
dynamicMember keyPath: KeyPath<(Substring, _doNotUse: ()), Substring>
43-
) -> Substring {
44-
anyRegexOutput.input[range]
45-
}
46-
47-
/// Access a capture by name. Returns `nil` if there's no capture with that name.
48-
public subscript(name: String) -> AnyRegexOutput.Element? {
49-
anyRegexOutput.first {
50-
$0.name == name
51-
}
52-
}
53-
}
54-
5514
/// A type-erased regex output.
5615
@available(SwiftStdlib 5.7, *)
5716
public struct AnyRegexOutput {
@@ -90,7 +49,7 @@ extension AnyRegexOutput: RandomAccessCollection {
9049
public struct Element {
9150
internal let representation: ElementRepresentation
9251
internal let input: String
93-
52+
9453
/// The range over which a value was captured. `nil` for no-capture.
9554
public var range: Range<String.Index>? {
9655
representation.bounds
@@ -160,19 +119,62 @@ extension AnyRegexOutput {
160119

161120
@available(SwiftStdlib 5.7, *)
162121
extension Regex.Match where Output == AnyRegexOutput {
163-
/// Creates a type-erased regex match from an existing match.
122+
/// Accesses the whole match using the `.0` syntax.
123+
public subscript(
124+
dynamicMember keyPath: KeyPath<(Substring, _doNotUse: ()), Substring>
125+
) -> Substring {
126+
anyRegexOutput.input[range]
127+
}
128+
129+
/// Access a capture by name. Returns `nil` if there's no capture with that name.
130+
public subscript(name: String) -> AnyRegexOutput.Element? {
131+
anyRegexOutput.first {
132+
$0.name == name
133+
}
134+
}
135+
}
136+
137+
// MARK: - Run-time regex creation and queries
138+
139+
@available(SwiftStdlib 5.7, *)
140+
extension Regex where Output == AnyRegexOutput {
141+
/// Parses and compiles a regular expression, resulting in an existentially-typed capture list.
164142
///
165-
/// Use this initializer to fit a regex match with strongly typed captures into the
166-
/// use site of a dynamic regex match, like one that was created from a string.
167-
public init<Output>(_ match: Regex<Output>.Match) {
168-
self.init(
169-
anyRegexOutput: match.anyRegexOutput,
170-
range: match.range,
171-
value: match.value
172-
)
143+
/// - Parameter pattern: The regular expression.
144+
public init(_ pattern: String) throws {
145+
self.init(ast: try parse(pattern, .semantic, .traditional))
146+
}
147+
}
148+
149+
@available(SwiftStdlib 5.7, *)
150+
extension Regex {
151+
/// Parses and compiles a regular expression.
152+
///
153+
/// - Parameter pattern: The regular expression.
154+
/// - Parameter as: The desired type for the output.
155+
public init(
156+
_ pattern: String,
157+
as: Output.Type = Output.self
158+
) throws {
159+
self.init(ast: try parse(pattern, .semantic, .traditional))
160+
}
161+
162+
/// Produces a regex that matches `verbatim` exactly, as though every
163+
/// metacharacter in it was escaped.
164+
public init(verbatim: String) {
165+
self.init(node: .quotedLiteral(verbatim))
166+
}
167+
168+
/// Returns whether a named-capture with `name` exists
169+
public func contains(captureNamed name: String) -> Bool {
170+
program.tree.root._captureList.captures.contains(where: {
171+
$0.name == name
172+
})
173173
}
174174
}
175175

176+
// MARK: - Converting to/from ARO
177+
176178
@available(SwiftStdlib 5.7, *)
177179
extension Regex where Output == AnyRegexOutput {
178180
/// Creates a type-erased regex from an existing regex.
@@ -184,6 +186,21 @@ extension Regex where Output == AnyRegexOutput {
184186
}
185187
}
186188

189+
@available(SwiftStdlib 5.7, *)
190+
extension Regex.Match where Output == AnyRegexOutput {
191+
/// Creates a type-erased regex match from an existing match.
192+
///
193+
/// Use this initializer to fit a regex match with strongly typed captures into the
194+
/// use site of a dynamic regex match, like one that was created from a string.
195+
public init<Output>(_ match: Regex<Output>.Match) {
196+
self.init(
197+
anyRegexOutput: match.anyRegexOutput,
198+
range: match.range,
199+
value: match.value
200+
)
201+
}
202+
}
203+
187204
@available(SwiftStdlib 5.7, *)
188205
extension Regex {
189206
/// Creates a strongly-typed regex from a dynamic regex, i.e. one created
@@ -192,21 +209,19 @@ extension Regex {
192209
/// Use this initializer to create a strongly typed regex from
193210
/// one that was created from a string. Returns `nil` if the types
194211
/// don't match.
195-
public init?(_ dynamic: Regex<AnyRegexOutput>) {
212+
public init?(
213+
_ dynamic: Regex<AnyRegexOutput>,
214+
as: Output.Type = Output.self
215+
) {
196216
self.init(node: dynamic.root)
197217
guard self._verifyType() else {
198218
return nil
199219
}
200220
}
201-
202-
/// Returns whether a named-capture with `name` exists
203-
public func contains(captureNamed name: String) -> Bool {
204-
program.tree.root._captureList.captures.contains(where: {
205-
$0.name == name
206-
})
207-
}
208221
}
209222

223+
// MARK: - Internals
224+
210225
@available(SwiftStdlib 5.7, *)
211226
extension AnyRegexOutput {
212227
/// The underlying representation of the element of a type-erased regex
@@ -251,12 +266,3 @@ extension AnyRegexOutput.ElementRepresentation {
251266
)
252267
}
253268
}
254-
255-
@available(SwiftStdlib 5.7, *)
256-
extension Regex {
257-
/// Produces a regex that matches `verbatim` exactly, as though every
258-
/// metacharacter in it was escaped.
259-
public init(verbatim: String) {
260-
self.init(node: .quotedLiteral(verbatim))
261-
}
262-
}

0 commit comments

Comments
 (0)