Last active
July 24, 2024 09:03
-
-
Save robnadin/128d73aa4b5f4011ad0cdb2bbca0ea4f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RegexBuilder | |
extension Regex { | |
/// Transforms the output of a regex component using the provided transformation function. | |
/// | |
/// - Parameter transform: A closure that takes the output of the regex and transforms it to a new output type. | |
/// - Returns: A new `Regex` instance that applies the transformation function to its output. | |
public func mapOutput<NewOutput>(_ transform: @escaping (Output) throws -> NewOutput) -> Regex<NewOutput> { | |
Regex<NewOutput> { | |
MapOutput(innerRegex: self, transform: transform) | |
} | |
} | |
} | |
private struct MapOutput<Output, NewOutput>: CustomConsumingRegexComponent { | |
typealias RegexOutput = NewOutput | |
let innerRegex: Regex<Output> | |
let transform: (Output) throws -> NewOutput | |
func consuming( | |
_ input: String, | |
startingAt index: String.Index, | |
in bounds: Range<String.Index>) throws -> (upperBound: String.Index, output: NewOutput)? | |
{ | |
guard index != bounds.upperBound, let match = input[index..<bounds.upperBound].prefixMatch(of: innerRegex) else { | |
return nil | |
} | |
let output = try transform(match.output) | |
return (match.range.upperBound, output) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment