extension PureYAML.Parsing { enum Event: Equatable, CustomStringConvertible { case streamStart(mark: Mark) case streamEnd(mark: Mark) case documentStart(explicit: Bool, mark: Mark) case documentEnd(explicit: Bool, mark: Mark) case sequenceStart(anchor: String?, tag: String?, style: CollectionStyle, mark: Mark) case sequenceEnd(mark: Mark) case mappingStart(anchor: String?, tag: String?, style: CollectionStyle, mark: Mark) case mappingEnd(mark: Mark) case scalar(value: String, anchor: String?, tag: String?, style: ScalarStyle, mark: Mark, endMark: Mark) case alias(anchor: String, mark: Mark) var description: String { switch self { case let .streamStart(mark): "streamStart @\(mark)" case let .streamEnd(mark): "streamEnd @\(mark)" case let .documentStart(explicit, mark): "documentStart explicit=\(explicit) @\(mark)" case let .documentEnd(explicit, mark): "documentEnd explicit=\(explicit) @\(mark)" case let .sequenceStart(anchor, tag, style, mark): "sequenceStart anchor=\(describe(anchor)) tag=\(describe(tag)) style=\(style) @\(mark)" case let .sequenceEnd(mark): "sequenceEnd @\(mark)" case let .mappingStart(anchor, tag, style, mark): "mappingStart anchor=\(describe(anchor)) tag=\(describe(tag)) style=\(style) @\(mark)" case let .mappingEnd(mark): "mappingEnd @\(mark)" case let .scalar(value, anchor, tag, style, mark, _): "scalar value=\"\(escape(value))\" anchor=\(describe(anchor)) tag=\(describe(tag)) style=\(style) @\(mark)" case let .alias(anchor, mark): "alias anchor=\(anchor) @\(mark)" } } } } extension PureYAML.Parsing.Event { /// Re-emit the event with libyaml's 0-based line/column mark converted to the /// package's 1-based convention (the byte index is already 0-based in both). func bumpingMark() -> Self { let source = mark let bumped = PureYAML.Parsing.Mark(line: source.line + 1, column: source.column + 1, index: source.index) switch self { case .streamStart: return .streamStart(mark: bumped) case .streamEnd: return .streamEnd(mark: bumped) case let .documentStart(explicit, _): return .documentStart(explicit: explicit, mark: bumped) case let .documentEnd(explicit, _): return .documentEnd(explicit: explicit, mark: bumped) case let .sequenceStart(anchor, tag, style, _): return .sequenceStart(anchor: anchor, tag: tag, style: style, mark: bumped) case .sequenceEnd: return .sequenceEnd(mark: bumped) case let .mappingStart(anchor, tag, style, _): return .mappingStart(anchor: anchor, tag: tag, style: style, mark: bumped) case .mappingEnd: return .mappingEnd(mark: bumped) case let .scalar(value, anchor, tag, style, _, endMark): let bumpedEnd = PureYAML.Parsing.Mark(line: endMark.line + 1, column: endMark.column + 1, index: endMark.index) return .scalar(value: value, anchor: anchor, tag: tag, style: style, mark: bumped, endMark: bumpedEnd) case let .alias(anchor, _): return .alias(anchor: anchor, mark: bumped) } } var isMappingEnd: Bool { if case .mappingEnd = self { return true } return false } var isSequenceEnd: Bool { if case .sequenceEnd = self { return true } return false } var isStreamEnd: Bool { if case .streamEnd = self { return true } return false } var mark: PureYAML.Parsing.Mark { switch self { case let .alias(_, mark), let .mappingEnd(mark), let .mappingStart(_, _, _, mark), let .scalar(_, _, _, _, mark, _), let .sequenceEnd(mark), let .sequenceStart(_, _, _, mark), let .streamEnd(mark), let .streamStart(mark): mark case let .documentEnd(_, mark), let .documentStart(_, mark): mark } } private func describe(_ value: String?) -> String { value ?? "-" } private func escape(_ value: String) -> String { var output = "" for character in value { switch character { case "\\": output += "\\\\" case "\"": output += "\\\"" case "\n": output += "\\n" case "\r": output += "\\r" case "\t": output += "\\t" default: output.append(character) } } return output } }