1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2021 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
/// A lazy sequence consisting of an element's child elements.
///
/// This is a `Sequence` and not a `Collection` because
/// information that locates a child element under a parent element is not
/// cached and calculated on demand.
public struct MarkupChildren: Sequence {
public struct Iterator: IteratorProtocol {
let parent: Markup
var childMetadata: MarkupMetadata
init(_ parent: Markup) {
self.parent = parent
self.childMetadata = parent.raw.metadata.firstChild()
}
public mutating func next() -> Markup? {
let index = childMetadata.indexInParent
guard index < parent.childCount else {
return nil
}
let rawChild = parent.raw.markup.child(at: index)
let absoluteRawChild = AbsoluteRawMarkup(markup: rawChild, metadata: childMetadata)
let data = _MarkupData(absoluteRawChild, parent: parent)
childMetadata = childMetadata.nextSibling(from: rawChild)
return makeMarkup(data)
}
}
/// The parent whose children this sequence represents.
let parent: Markup
/// Create a lazy sequence of an element's children.
///
/// - parameter parent: the parent whose children this sequence represents.
init(_ parent: Markup) {
self.parent = parent
}
// MARK: Sequence
public func makeIterator() -> Iterator {
return Iterator(parent)
}
/// A reversed view of the element's children.
public func reversed() -> ReversedMarkupChildren {
return ReversedMarkupChildren(parent)
}
}
/// A sequence consisting of an element's child elements in reverse.
///
/// This is a `Sequence` and not a `Collection` because
/// information that locates a child element under a parent element is not
/// cached and calculated on demand.
public struct ReversedMarkupChildren: Sequence {
public struct Iterator: IteratorProtocol {
/// The parent whose children this sequence represents.
///
/// This is also necessary for creating an "absolute" child from
/// parentless ``RawMarkup``.
let parent: Markup
/// The metadata to use when creating an absolute child element.
var childMetadata: MarkupMetadata
init(_ parent: Markup) {
self.parent = parent
self.childMetadata = parent.raw.metadata.lastChildMetadata(of: parent.raw.markup)
}
public mutating func next() -> Markup? {
let index = childMetadata.indexInParent
guard index >= 0 else {
return nil
}
let rawChild = parent.raw.markup.child(at: index)
let absoluteRawChild = AbsoluteRawMarkup(markup: rawChild, metadata: childMetadata)
let data = _MarkupData(absoluteRawChild, parent: parent)
childMetadata = childMetadata.previousSibling(from: rawChild)
return makeMarkup(data)
}
}
/// The parent whose children this sequence represents.
let parent: Markup
/// Create a reversed view of an element's children.
///
/// - parameter parent: The parent whose children this sequence will represent.
init(_ parent: Markup) {
self.parent = parent
}
// MARK: Sequence
public func makeIterator() -> Iterator {
return Iterator(parent)
}
}
|