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() var inheritedPairs: [PureYAML.Model.Pair] = [] for source in mergeSources { var sourceKeys = Set() 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, ) } } }