Created
October 21, 2020 23:21
-
-
Save bok-/07f8b691b6d0ae9bd44ea212f1fc39d4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@_functionBuilder | |
public enum CollectionBuilder<Component> { | |
// MARK: - Building Expressions | |
/// Basic uplift of an `Expression` into a `Component` (aka `[Expression]`) | |
/// | |
public static func buildExpression(_ expression: Component) -> [Component] { | |
[expression] | |
} | |
/// Support for optional `Expression`s in your resut builder | |
/// | |
public static func buildExpression(_ expression: Component?) -> [Component] { | |
[] | |
} | |
// MARK: - Building Blocks | |
/// Support for result builders that return no children or void | |
/// | |
public static func buildBlock() -> [Component] { | |
[] | |
} | |
/// Support for multiple lines of `Component`s | |
/// | |
public static func buildBlock(_ components: [Component]...) -> [Component] { | |
components.flatMap { $0 } | |
} | |
// MARK: - Building Conditionals | |
/// Support for single-branch conditional statements (eg an `if` statement without an `else` branch) | |
/// | |
public static func buildOptional(_ components: [Component]?) -> [Component] { | |
components ?? [] | |
} | |
/// Support for multi-branch conditional statements (eg an `if` statement with an `else` branch) | |
/// | |
public static func buildEither(first: [Component]) -> [Component] { | |
first | |
} | |
/// Support for multi-branch conditional statements (eg an `if` statement with an `else` branch) | |
/// | |
public static func buildEither(second: [Component]) -> [Component] { | |
second | |
} | |
/// Support for `if #available` statements, we don't really need this as we're not trying | |
/// to type-erase whats inside the availability statement, but @bok is a completionist so ¯\_(ツ)_/¯ | |
/// | |
public static func buildLimitedAvailability(_ components: [Component]) -> [Component] { | |
components | |
} | |
} | |
// MARK: - Array Support | |
public extension Array { | |
/// Initialises an Array with the results returned by a function builder | |
/// | |
init(@CollectionBuilder<Element> collecting: () -> [Element]) { | |
self = collecting() | |
} | |
/// Adds the results of the function builder to the Array | |
/// | |
mutating func collect(@CollectionBuilder<Element> _ builder: () -> [Element]) { | |
append(contentsOf: builder()) | |
} | |
} | |
// MARK: - Set Support | |
public extension Set { | |
/// Initialises a Set with the results returned by a function builder | |
/// | |
init(@CollectionBuilder<Element> collecting: () -> [Element]) { | |
self.init(collecting()) | |
} | |
/// Adds the results of the function builder to the Set | |
/// | |
mutating func collect(@CollectionBuilder<Element> _ builder: () -> [Element]) { | |
for element in builder() { | |
insert(element) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment