diff --git a/Package.swift b/Package.swift index 1c71e07e..7928a6d1 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.5 +// swift-tools-version:5.7 /* This source file is part of the Swift.org open source project diff --git a/Sources/Markdown/Visitor/MarkupVisitor.swift b/Sources/Markdown/Visitor/MarkupVisitor.swift index f979e42d..ed2cd411 100644 --- a/Sources/Markdown/Visitor/MarkupVisitor.swift +++ b/Sources/Markdown/Visitor/MarkupVisitor.swift @@ -1,7 +1,7 @@ /* This source file is part of the Swift.org open source project - Copyright (c) 2021 Apple Inc. and the Swift project authors + Copyright (c) 2021-2023 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 @@ -13,7 +13,7 @@ /// - note: This interface only provides requirements for visiting each kind of element. It does not require each visit method to descend into child elements. /// /// Generally, ``MarkupWalker`` is best for walking a ``Markup`` tree if the ``Result`` type is `Void` or is built up some other way, or ``MarkupRewriter`` for recursively changing a tree's structure. This type serves as a common interface to both. However, for building up other structured result types you can implement ``MarkupVisitor`` directly. -public protocol MarkupVisitor { +public protocol MarkupVisitor { /** The result type returned when visiting a element. diff --git a/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift new file mode 100644 index 00000000..464c8a6a --- /dev/null +++ b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift @@ -0,0 +1,56 @@ +/* + This source file is part of the Swift.org open source project + + Copyright (c) 2023 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 XCTest +import Markdown + +class MarkupVisitorTests: XCTestCase { + struct IntegerConverter: MarkupVisitor { + var value: Int + + mutating func defaultVisit(_: Markdown.Markup) -> Int { + defer { value += 1 } + return value + } + } + + + // A compile time check for PAT support + func testMarkupVisitorPrimaryAssociatedType() { + var visitor: some MarkupVisitor = IntegerConverter(value: 1) + let markup = Text("") + XCTAssertEqual(visitor.visit(markup), 1) + XCTAssertEqual(visitor.visit(markup), 2) + var mappedVisitor: some MarkupVisitor = visitor.map { $0 * $0 } + XCTAssertEqual(mappedVisitor.visit(markup), 9) + XCTAssertEqual(mappedVisitor.visit(markup), 16) + XCTAssertEqual(visitor.visit(markup), 3) + } +} + +struct _MappVisitor: MarkupVisitor { + typealias Result = B + init(visitor: A, _ transform: @escaping (A.Result) -> B) { + self.visitor = visitor + self.transform = transform + } + private var visitor: A + private let transform: (A.Result) -> B + + mutating func defaultVisit(_ markup: Markdown.Markup) -> B { + transform(visitor.defaultVisit(markup)) + } +} + +extension MarkupVisitor { + func map(_ transform: @escaping (Self.Result) -> U) -> some MarkupVisitor { + _MappVisitor(visitor: self, transform) + } +}