in Cyborg/ParserPrimitives.swift [157:217]
func consumeAll<T>(using parsers: [Parser<T>]) -> Parser<ContiguousArray<T>> {
return { (stream: XMLString, index: Int32) in
var index = index,
results: ContiguousArray<T> = [],
errors: ContiguousArray<Failure> = []
errors.reserveCapacity(parsers.count)
results.reserveCapacity(Int(stream.count) / 3)
var next = index
untilNoMatchFound:
while true {
next = index
while next != stream.count,
(stream[next] == .whitespace || stream[next] == .newline) {
next += 1
}
checkAllParsers:
for parser in parsers {
switch parser(stream, next) {
case .ok(let result, let currentIndex):
results.append(result)
index = currentIndex
errors.removeAll()
continue untilNoMatchFound
case .error(let error):
errors.append(error)
}
}
if index == stream.count {
return .ok(results, index)
} else {
if errors.first(where: { (error: Failure) -> Bool in
if case .literalNotFoundAtIndex = error {
return false
} else {
return true
}
}) == nil {
return .error(.noParsersMatchedFirstCharacter(stream[next], .init(index: next, stream: stream)))
} else {
var furthestError = errors.first
var foundUnequalIndex = false
for error in errors.dropFirst() {
let lastIndex = furthestError?.index ?? -1
if error.index != lastIndex {
foundUnequalIndex = true
if error.index > lastIndex {
furthestError = error
}
}
}
if let furthestError = furthestError,
foundUnequalIndex {
return .error(furthestError)
} else {
return .error(.allParsersFailed(Array(errors), .init(index: next, stream: stream)))
}
}
}
}
}
}