File: LazySplitLines.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (71 lines) | stat: -rw-r--r-- 2,291 bytes parent folder | download
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
/*
 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
*/

import Foundation

/// A lazy sequence of split lines that keeps track of initial indentation and
/// consecutive runs of empty lines.
struct LazySplitLines: Sequence {
    struct Iterator: IteratorProtocol {
        /// The current running count of consecutive empty lines before the current iteration.
        private var precedingConsecutiveEmptyLineCount = 0

        /// The raw lines to be iterated.
        private let rawLines: [Substring]

        /// The current index of the iteration.
        private var index: Array<Substring>.Index

        /// The source file or resource from which the line came,
        /// or `nil` if no such file or resource can be identified.
        private var source: URL?

        init<S: StringProtocol>(_ input: S, source: URL?) where S.SubSequence == Substring {
            self.rawLines = input.split(separator: "\n", maxSplits: Int.max, omittingEmptySubsequences: false)
            self.index = rawLines.startIndex
            self.source = source
        }

        mutating func next() -> TrimmedLine? {
            guard index != rawLines.endIndex else {
                return nil
            }

            let segment = TrimmedLine(rawLines[index], source: source, lineNumber: index + 1)

            index = rawLines.index(after: index)

            if segment.text.isEmpty {
                precedingConsecutiveEmptyLineCount += 1
            } else {
                precedingConsecutiveEmptyLineCount = 0
            }

            return segment
        }
    }

    /// The input to be lazily split on newlines.
    private let input: Substring

    /// The source file or resource from which the line came,
    /// or `nil` if no such file or resource can be identified.
    private let source: URL?

    init(_ input: Substring, source: URL?) {
        self.input = input
        self.source = source
    }

    func makeIterator() -> Iterator {
        return Iterator(input, source: source)
    }
}