Last active
March 23, 2023 08:07
-
-
Save JadenGeller/c375fc15ad5900a0ddac4ed8ba8307a9 to your computer and use it in GitHub Desktop.
ArrayBuilder
This file contains 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
@resultBuilder | |
struct ArrayBuilder<Element> { | |
enum Component { | |
case atom(Element) | |
case spread([Component]) | |
} | |
static func buildBlock(_ elements: Component...) -> Component { | |
.spread(elements) | |
} | |
static func buildExpression(_ element: Element) -> Component { | |
.atom(element) | |
} | |
static func buildExpression(_ component: Component) -> Component { | |
component | |
} | |
static func buildOptional(_ component: Component?) -> Component { | |
component ?? .spread([]) | |
} | |
static func buildEither(first component: Component) -> Component { | |
component | |
} | |
static func buildEither(second component: Component) -> Component { | |
component | |
} | |
static func buildArray(_ components: [Component]) -> Component { | |
.spread(components) | |
} | |
static func buildFinalResult(_ component: Component) -> [Element] { | |
Array(component) | |
} | |
} | |
extension Array { | |
init(_ component: ArrayBuilder<Element>.Component) { | |
switch component { | |
case .atom(let element): | |
self = [element] | |
case .spread(let components): | |
self = components.flatMap(Array.init) | |
} | |
} | |
init(@ArrayBuilder<Element> build: () -> [Element]) { | |
self = build() | |
} | |
} | |
prefix func ...<S: Sequence>(_ sequence: S) -> ArrayBuilder<S.Element>.Component { | |
.spread(sequence.map(ArrayBuilder.Component.atom)) | |
} |
This file contains 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
@resultBuilder | |
struct ArrayBuilder<Element> { | |
enum Component { | |
case spread([Element]) | |
} | |
static func buildBlock(_ components: Component...) -> Component { | |
ArrayBuilder.buildArray(components) | |
} | |
static func buildExpression(_ element: Element) -> Component { | |
.spread([element]) | |
} | |
static func buildExpression(_ component: Component) -> Component { | |
component | |
} | |
static func buildOptional(_ component: Component?) -> Component { | |
component ?? .spread([]) | |
} | |
static func buildEither(first component: Component) -> Component { | |
component | |
} | |
static func buildEither(second component: Component) -> Component { | |
component | |
} | |
static func buildArray(_ components: [Component]) -> Component { | |
.spread(components.flatMap(Array.init)) | |
} | |
static func buildFinalResult(_ component: Component) -> [Element] { | |
Array(component) | |
} | |
} | |
extension Array { | |
init(_ component: ArrayBuilder<Element>.Component) { | |
switch component { | |
case .spread(let elements): | |
self = elements | |
} | |
} | |
init(@ArrayBuilder<Element> build: () -> [Element]) { | |
self = build() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment