File: WITBuilder.swift

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (137 lines) | stat: -rw-r--r-- 3,403 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
protocol SourcePrintable {
    func print(printer: SourcePrinter)
}
struct WITRecord {
    struct Field {
        var name: String
        var type: String
    }
    var name: String
    var fields: [Field]
}

extension WITRecord: SourcePrintable {
    func print(printer: SourcePrinter) {
        printer.write(line: "record \(name) {")
        printer.indent {
            for field in fields {
                printer.write(line: "\(field.name): \(field.type),")
            }
        }
        printer.write(line: "}")
    }
}

struct WITVariant {
    struct Case {
        var name: String
        var type: String?
    }
    var name: String
    var cases: [Case]
}

extension WITVariant: SourcePrintable {
    func print(printer: SourcePrinter) {
        printer.write(line: "variant \(name) {")
        printer.indent {
            for variantCase in cases {
                if let payloadType = variantCase.type {
                    printer.write(line: "\(variantCase.name)(\(payloadType)),")
                } else {
                    printer.write(line: "\(variantCase.name),")
                }
            }
        }
        printer.write(line: "}")
    }
}

struct WITEnum {
    var name: String
    var cases: [String]
}

extension WITEnum: SourcePrintable {
    func print(printer: SourcePrinter) {
        printer.write(line: "enum \(name) {")
        printer.indent {
            for enumCase in cases {
                printer.write(line: "\(enumCase),")
            }
        }
        printer.write(line: "}")
    }
}

struct WITFunction {
    struct Parameter {
        let name: String
        let type: String
    }
    enum Results {
        case named([Parameter])
        case anon(String)
    }
    let name: String
    let parameters: [Parameter]
    let results: Results
}

extension WITFunction: SourcePrintable {
    func print(printer: SourcePrinter) {
        func paramsString(_ parameters: [Parameter]) -> String {
            parameters.map {
                "\($0.name): \($0.type)"
            }.joined(separator: ", ")
        }
        let params = paramsString(parameters)
        let result: String
        switch results {
        case .anon(let type):
            result = " -> " + type
        case .named(let types):
            if !types.isEmpty {
                result = " -> (" + paramsString(types) + ")"
            } else {
                result = ""
            }
        }
        printer.write(line: name + ": func(\(params))" + result)
    }
}

struct WITBuilder {
    let interfaceName: String
    var definitions: [SourcePrintable] = []

    mutating func define(record: WITRecord) {
        definitions.append(record)
    }

    mutating func define(variant: WITVariant) {
        definitions.append(variant)
    }

    mutating func define(enum: WITEnum) {
        definitions.append(`enum`)
    }

    mutating func define(function: WITFunction) {
        definitions.append(function)
    }

    func print(printer: SourcePrinter) {
        printer.write(line: "interface \(interfaceName) {")
        printer.indent {
            for (index, type) in definitions.enumerated() {
                type.print(printer: printer)
                let isLast = index == definitions.count - 1
                if !isLast {
                    printer.emptyLine()
                }
            }
        }
        printer.write(line: "}")
    }
}