nitpick in "Detailed design" > "CustomConsumingRegexComponent":
func consuming(
_ input: String,
startingAt index: String.Index,
in bounds: Range<String.Index>
) throws -> (upperBound: String.Index, match: Match)?
The return type should be (upperBound: String.Index, output: RegexOutput)?, shouldn't it?
One more thing.
There is explanation why Collection is used instead of Sequence and why it's Collection where SubSequence == Substring. But, is there any explanation why not StringProtocol where SubSequence == Substring and StringProtocol where Self: RangeReplaceableCollection?
This is just a question. I don’t necessarily hope that, though.