The buffered and streaming event composers each carried an identical copy of the merge-key (<<) override logic and its invalid-value error. Extract both into one internal Parsing.MergeResolution helper so the precedence rules (local keys win, earlier sources win, inherited then local order) have a single source of truth. No behavior change; all tests pass.
47 lines
1.8 KiB
Swift
47 lines
1.8 KiB
Swift
extension PureYAML.Parsing {
|
|
/// Shared merge-key (`<<`) resolution used by both the buffered and the
|
|
/// streaming event composers, so the override semantics live in one place.
|
|
enum MergeResolution {
|
|
/// Combine merge sources with local pairs.
|
|
///
|
|
/// Local keys win over inherited keys, and earlier merge sources win
|
|
/// over later ones. Insertion order is inherited pairs first, then the
|
|
/// document's own local pairs.
|
|
static func mergedPairs(
|
|
from mergeSources: [[PureYAML.Model.Pair]],
|
|
localPairs: [PureYAML.Model.Pair],
|
|
) -> [PureYAML.Model.Pair] {
|
|
guard !mergeSources.isEmpty else {
|
|
return localPairs
|
|
}
|
|
|
|
let localKeys = Set(localPairs.map(\.keyNode))
|
|
var inheritedKeys = Set<PureYAML.Model.Key>()
|
|
var inheritedPairs: [PureYAML.Model.Pair] = []
|
|
for source in mergeSources {
|
|
var sourceKeys = Set<PureYAML.Model.Key>()
|
|
for pair in source {
|
|
guard !localKeys.contains(pair.keyNode),
|
|
!inheritedKeys.contains(pair.keyNode)
|
|
else {
|
|
continue
|
|
}
|
|
inheritedPairs.append(pair)
|
|
sourceKeys.insert(pair.keyNode)
|
|
}
|
|
inheritedKeys.formUnion(sourceKeys)
|
|
}
|
|
return inheritedPairs + localPairs
|
|
}
|
|
|
|
/// The parse error raised when a merge value is neither a mapping nor a
|
|
/// sequence of mappings.
|
|
static func invalidMergeValue(mark: PureYAML.Parsing.Mark) -> PureYAML.Parsing.ParseError {
|
|
PureYAML.Parsing.ParseError.invalidMergeValue(
|
|
line: mark.line,
|
|
column: mark.column,
|
|
)
|
|
}
|
|
}
|
|
}
|