builder-macro
is a macro that implements the Builder design pattern in Swift.
import BuilderMacro
@Builder
struct Person {
let id: UUID
let name: String
let bday: Date
}
// Expanded
struct Person {
let firstName: String, let lastName: String, let middleName: String
let birthday: Date
let city: String
struct PersonBuilder {
var firstName: String?
var lastName: String?
var middleName: String?
var birthday: Date?
var city: String?
func firstName(_ firstName: String) -> Self {
var copy = self
copy.firstName = firstName
return copy
}
func lastName(_ lastName: String) -> Self {
var copy = self
copy.lastName = lastName
return copy
}
func middleName(_ middleName: String) -> Self {
var copy = self
copy.middleName = middleName
return copy
}
func birthday(_ birthday: Date) -> Self {
var copy = self
copy.birthday = birthday
return copy
}
func city(_ city: String) -> Self {
var copy = self
copy.city = city
return copy
}
enum BuildError: Swift.Error {
case missingRequiredField(description: String)
}
func build() throws -> Person {
guard let firstName = firstName else {
throw BuildError.missingRequiredField(description: "firstName")
}
guard let lastName = lastName else {
throw BuildError.missingRequiredField(description: "lastName")
}
guard let middleName = middleName else {
throw BuildError.missingRequiredField(description: "middleName")
}
guard let birthday = birthday else {
throw BuildError.missingRequiredField(description: "birthday")
}
guard let city = city else {
throw BuildError.missingRequiredField(description: "city")
}
return Person(
firstName: firstName,
lastName: lastName,
middleName: middleName,
birthday: birthday,
city: city
)
}
}
}
If a property type is optional, you can force validation of nil values by passing the addGuards parameter to the builder macro like this::
import BuilderMacro
@Builder(addGuards: true)
struct Person {
let id: UUID
let name: String
let bday: Date
}
- iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
- Xcode 15.0
- Swift 5.9
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into the swift
compiler. It is in early development, but builder-macro
does support its use on supported platforms.
Once you have your Swift package set up, adding builder-macro
as a dependency is as easy as adding it to the dependencies
value of your Package.swift
.
dependencies: [
.package(url: "https://github.com/space-code/builder-macro.git", .upToNextMajor(from: "1.0.0"))
]
- If you found a bug, open an issue.
- If you have a feature request, open an issue.
- If you want to contribute, submit a pull request.
Bootstrapping development environment
make bootstrap
Please feel free to help out with this project! If you see something that could be made better or want a new feature, open up an issue or send a Pull Request!
Nikita Vasilev, [email protected]
builder-macro is available under the MIT license. See the LICENSE file for more info.