-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.swift
109 lines (93 loc) · 2.53 KB
/
main.swift
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
//
// main.swift
//
// Created by Ahmed Ali (github.com/Ahmed-Ali) on 22/04/2024.
//
import BuildDSL
import Foundation
import os
let logger = Logger(subsystem: "Examples", category: "BuildDSL")
/**
Example usages of the @Builder macro and its suplimentary @Default, @Ignore and @Escaping macros.
Try to right click and choose the "Expand Macro" option to get better idea of what code being generated and how it works
*/
@Builder
public struct Talk {
let speaker: String
let topic: String
@Ignore
let maxDuration: Int = 20
}
@Builder
struct Schedule {
@Default(Date.timeIntervalSinceReferenceDate)
let startTime: TimeInterval
/**
Becaue the Talk struct also
uses the `@Builder` macro
you will get two setters
normal one
`.keynote(Talk(speaker:topic:))`
and another nested builder
```
.keynoteBuilder { talk in
}
```
*/
let keynote: Talk
// Use can also regular Swift defaults
var talks: [Talk] = []
}
@Builder
struct Conferance {
let name: String
let schedule: Schedule
let sendInvitation: (String) -> Void
}
// All builders have a optional initializer
let conference = Conferance { $0
.name("Hot NSTalk")
.sendInvitation { destination in
print("Sending invitation to: \(destination)")
}
// Any nested struct that also has a builder
// will have a setter using a result builder
.scheduleBuilder { schedule in
schedule
// you can also use the non-builder setter
.keynote(Talk(speaker: "Keynote Speakr", topic: "Key note"))
.talks([
Talk(speaker: "Speaker 1", topic: "Topic 1"),
Talk(speaker: "Speaker 2", topic: "Topic 2")
])
}
}
logger.info("\(String(reflecting: conference))")
conference!.sendInvitation("Swift Devs")
// You can also use the `build` for better error report
do {
let conf = try Conferance.build { $0
.schedule(
Schedule { $0
.keynoteBuilder { $0
.speaker("")
.topic("")
}
}!
)
}.get()
logger.info("\(String(reflecting: conf))")
} catch {
logger.error("\(String(describing: error))")
}
// you can also offer the builder API through your methods
func create(@Talk.ResultBuilder talk resultBuilder: Talk.Closure) -> Talk.Result {
Talk.build(resultBuilder)
}
let talk = create { talk in
p(talk)
}
logger.info("\(String(describing: talk))")
func p(_ v: Talk.Builder) -> Talk.Builder {
v
}