Replace the line-based --- heuristic with a scan over PureYAML's resumable token scanner, so a --- inside a quoted scalar can no longer misfire as a document boundary and directives stay attached to the document they introduce. Add a differential suite that checks the new scanner against the old line-based reference across generated streams and the full Geekbench corpus.
55 lines
1.8 KiB
Swift
55 lines
1.8 KiB
Swift
import Foundation
|
|
import PureYAML
|
|
@testable import PureYAMLStreaming
|
|
|
|
/// The integer stored under `key` when `value` is a mapping, or nil.
|
|
func intValue(_ key: String, in value: PureYAML.Model.Value) -> Int? {
|
|
guard case let .mapping(mapping) = value,
|
|
case let .int(number)? = mapping[key]
|
|
else {
|
|
return nil
|
|
}
|
|
return number
|
|
}
|
|
|
|
/// Splits `input` into chunks of `size` Unicode scalars, so a chunk boundary
|
|
/// can land anywhere: mid-line, mid-token, and mid-grapheme.
|
|
func scalarChunks(_ input: String, size: Int) -> [String] {
|
|
precondition(size > 0)
|
|
let scalars = Array(input.unicodeScalars)
|
|
var chunks: [String] = []
|
|
var index = 0
|
|
while index < scalars.count {
|
|
let end = min(index + size, scalars.count)
|
|
chunks.append(String(String.UnicodeScalarView(scalars[index ..< end])))
|
|
index = end
|
|
}
|
|
return chunks
|
|
}
|
|
|
|
/// All document sources the rewired scanner emits for `input` fed in
|
|
/// `chunkSize`-scalar chunks, in emission order.
|
|
func rewiredSegments(_ input: String, chunkSize: Int) throws -> [String] {
|
|
var scanner = PureYAMLStreaming.ResumableDocumentScanner()
|
|
var segments: [String] = []
|
|
for chunk in scalarChunks(input, size: chunkSize) {
|
|
segments += try scanner.consume(chunk)
|
|
}
|
|
segments += try scanner.finish()
|
|
return segments
|
|
}
|
|
|
|
/// All document sources the frozen line-based reference emits for `input` fed
|
|
/// in `chunkSize`-scalar chunks, in emission order.
|
|
func referenceSegments(_ input: String, chunkSize: Int) throws -> [String] {
|
|
var scanner = LineBasedReferenceScanner()
|
|
var segments: [String] = []
|
|
for chunk in scalarChunks(input, size: chunkSize) {
|
|
segments += try scanner.consume(chunk)
|
|
}
|
|
if let final = try scanner.finish() {
|
|
segments.append(final)
|
|
}
|
|
return segments
|
|
}
|