Skip to content

Commit 365bf2d

Browse files
authored
Add primary associated type for MarkupVisitor (#135)
* Add primary associated type for MarkupVisitor * Add test case for MarkupVisitor * Update testMarkupVisitorPrimaryAssociatedType
1 parent 49beeeb commit 365bf2d

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// swift-tools-version:5.5
1+
// swift-tools-version:5.7
22
/*
33
This source file is part of the Swift.org open source project
44

Sources/Markdown/Visitor/MarkupVisitor.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift.org open source project
33

4-
Copyright (c) 2021 Apple Inc. and the Swift project authors
4+
Copyright (c) 2021-2023 Apple Inc. and the Swift project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -13,7 +13,7 @@
1313
/// - note: This interface only provides requirements for visiting each kind of element. It does not require each visit method to descend into child elements.
1414
///
1515
/// 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.
16-
public protocol MarkupVisitor {
16+
public protocol MarkupVisitor<Result> {
1717

1818
/**
1919
The result type returned when visiting a element.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import XCTest
12+
import Markdown
13+
14+
class MarkupVisitorTests: XCTestCase {
15+
struct IntegerConverter: MarkupVisitor {
16+
var value: Int
17+
18+
mutating func defaultVisit(_: Markdown.Markup) -> Int {
19+
defer { value += 1 }
20+
return value
21+
}
22+
}
23+
24+
25+
// A compile time check for PAT support
26+
func testMarkupVisitorPrimaryAssociatedType() {
27+
var visitor: some MarkupVisitor<Int> = IntegerConverter(value: 1)
28+
let markup = Text("")
29+
XCTAssertEqual(visitor.visit(markup), 1)
30+
XCTAssertEqual(visitor.visit(markup), 2)
31+
var mappedVisitor: some MarkupVisitor<Int> = visitor.map { $0 * $0 }
32+
XCTAssertEqual(mappedVisitor.visit(markup), 9)
33+
XCTAssertEqual(mappedVisitor.visit(markup), 16)
34+
XCTAssertEqual(visitor.visit(markup), 3)
35+
}
36+
}
37+
38+
struct _MappVisitor<A: MarkupVisitor, B>: MarkupVisitor {
39+
typealias Result = B
40+
init(visitor: A, _ transform: @escaping (A.Result) -> B) {
41+
self.visitor = visitor
42+
self.transform = transform
43+
}
44+
private var visitor: A
45+
private let transform: (A.Result) -> B
46+
47+
mutating func defaultVisit(_ markup: Markdown.Markup) -> B {
48+
transform(visitor.defaultVisit(markup))
49+
}
50+
}
51+
52+
extension MarkupVisitor {
53+
func map<U>(_ transform: @escaping (Self.Result) -> U) -> some MarkupVisitor<U> {
54+
_MappVisitor(visitor: self, transform)
55+
}
56+
}

0 commit comments

Comments
 (0)