BuildDSL is a Swift package that offers a robust Domain-Specific Language (DSL) for crafting intuitive builder APIs for Swift structs. It streamlines the creation of complex objects with a clean, type-safe syntax, utilizing Swift's @resultBuilder, protocols, and generics, along with an auto-generated Builder pattern.
- Type-Safe Builder Pattern: Auto-generate builders for Swift structs with compile-time type checks.
- Declarative Syntax: Employ a succinct DSL to outline your object construction.
- Automatic Code Generation: Minimize boilerplate with auto-generated builder code.
- Nested Builders: Seamlessly construct complex objects using nested builders.
- Error Handling: Utilize Resulttypes for comprehensive error handling.
- Customizable Defaults: Specify default values for immutable fields with @Default.
- Property Exclusion: Omit properties from the builder with @Ignore.
- Swift 5.9+
- iOS 13.0+ / macOS 11.0+ / tvOS 13.0+ / watchOS 6.0+ / visionOS 1.0+
- Xcode 15.0+
Add BuildDSL to your project with Swift Package Manager by including the following in your Package.swift:
dependencies: [
    .package(url: "https://github.com/Ahmed-Ali/BuildDSL.git", from: "0.1.0")
]Or add it through Xcode by going to File > Add Package Dependencies and enter:
https://github.com/Ahmed-Ali/BuildDSL.git
Annotate your struct with @Builder and use the generated builder API:
import BuildDSL
@Builder
struct Person {
    let name: String
    let email: String
    @Default(Date())
    let createdAt: Date
    @Ignore
    var isVerified: Bool = false
}
// Create instances using the fluent builder API
let result = Person.build { $0
    .name("John Doe")
    .email("john@example.com")
}
switch result {
case .success(let person):
    print("Created: \(person)")
case .failure(let error):
    print("Build failed: \(error)")
}The full API documentation is available online, including:
- Getting Started Guide: Learn the basics with step-by-step examples
- API Reference: Complete documentation for all macros and types
- Advanced Patterns: Sophisticated usage scenarios and best practices
- Migration Guide: How to integrate BuildDSL into existing projects
- @Builder: The core macro for generating builder patterns
- @Default: Setting default values for properties
- @Ignore: Excluding properties from builders
- @Escaping: Handling closure properties
- BuilderError: Error handling in builders
For comprehensive examples, see:
- Sources/BuildDSLClient/main.swift - Real-world usage examples
- Tests/BuildDSLTests/MacroUsageTests.swift - Test cases covering all features
- 
Why use @resultBuilderinstead of a closure?
 @resultBuilderensures the closure is solely used for object construction, preventing arbitrary code execution and potential misuse.
- 
Are there benefits to using Builder pattern + @resultBuilderover just a Builder?
 Yes, it enhances discoverability and IDE assistance, making it easier to understand how to initialize objects with complex configurations.
- Initialization: Structs must have a memberwise initializer. Exclude properties with @Ignoreand provide default values or implement the initializer yourself.
- Buildable Dependencies: Declare dependent structs before dependees to ensure proper macro execution and avoid compilation errors.
- Autocomplete: While macros and Swift's Generics with @resultBuilderare powerful, IDE autocomplete may be less helpful with complex nested types. Patience and manual code entry may be required at times.
Contributions are welcomed! Here's how you can help:
- Fork the repository
- Create a feature branch (git checkout -b feature/amazing-feature)
- Add tests for your changes
- Ensure all tests pass (swift test)
- Run SwiftLint (swiftlint)
- Commit your changes (git commit -m 'Add amazing feature')
- Push to the branch (git push origin feature/amazing-feature)
- Create a Pull Request
Please make sure to:
- Write tests for any new functionality
- Follow the existing code style and conventions
- Update documentation if needed
- Ensure CI passes
BuildDSL is released under the MIT License. See LICENSE for details.
Happy building with BuildDSL! 🚀