| 
 | 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