From 3ec4aa86719d74d2cc5ac845635233996a32b499 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 6 Jul 2023 22:54:58 +0800 Subject: [PATCH 1/3] Add primary associated type for MarkupVisitor --- Package.swift | 2 +- Sources/Markdown/Visitor/MarkupVisitor.swift | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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. From f28afae376b363b761b3c90e8a9f8a732892e8f6 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 6 Jul 2023 23:16:02 +0800 Subject: [PATCH 2/3] Add test case for MarkupVisitor --- .../Visitors/MarkupVisitorTests.swift | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift diff --git a/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift new file mode 100644 index 00000000..9a2a3032 --- /dev/null +++ b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift @@ -0,0 +1,26 @@ +/* + 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 EmptyWalker: MarkupWalker { + mutating func defaultVisit(_ markup: Markdown.Markup) -> Void { + return + } + } + + // A compile time check for PAT support + func testMarkupVisitorPrimaryAssociatedType() { + var vistor: some MarkupVisitor = EmptyWalker() + vistor.visit(Text("")) + } +} From 96f0ebd7ec726d4315ad9b6292ff4c87db5beefd Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 21 Sep 2023 11:47:42 +0800 Subject: [PATCH 3/3] Update testMarkupVisitorPrimaryAssociatedType --- .../Visitors/MarkupVisitorTests.swift | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift index 9a2a3032..464c8a6a 100644 --- a/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift +++ b/Tests/MarkdownTests/Visitors/MarkupVisitorTests.swift @@ -12,15 +12,45 @@ import XCTest import Markdown class MarkupVisitorTests: XCTestCase { - struct EmptyWalker: MarkupWalker { - mutating func defaultVisit(_ markup: Markdown.Markup) -> Void { - return + 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 vistor: some MarkupVisitor = EmptyWalker() - vistor.visit(Text("")) + 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) } }