Skip to content

Latest commit

 

History

History
167 lines (132 loc) · 5.67 KB

README.md

File metadata and controls

167 lines (132 loc) · 5.67 KB

BuilderMacro is a macro that implements the Builder design pattern in Swift

builder-macro

License Swift Compatibility Platform Compatibility CodeCov CI GitHub release; latest by date

Description

builder-macro is a macro that implements the Builder design pattern in Swift.

Usage

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
}

Requirements

  • iOS 13.0+ / macOS 10.15+ / tvOS 13.0+ / watchOS 6.0+
  • Xcode 15.0
  • Swift 5.9

Installation

Swift Package Manager

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"))
]

Communication

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

Contributing

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!

Author

Nikita Vasilev, nv3212@gmail.com

License

builder-macro is available under the MIT license. See the LICENSE file for more info.