// // NodeListBuilder.swift // NodeItems // // Created by Casey Fleser on 3/2/23. // import SwiftUI @resultBuilder struct NodeListBuilder { typealias P = Node typealias OneOf = NodeAB static func buildPartialBlock(first c: [C]) -> [C] { c } // matching types static func buildPartialBlock(accumulated c0: [C], next c1: [C]) -> [C] { c0 + c1 } // matches A of OneOf static func buildPartialBlock(accumulated ab: [OneOf], next a: [A]) -> [OneOf] { ab + a.map { .a($0) } } // matches B of OneOf static func buildPartialBlock(accumulated ab: [OneOf], next b: [B]) -> [OneOf] { ab + b.map { .b($0) } } // matches A of OneOf, C> static func buildPartialBlock(accumulated abc: [OneOf, C>], next a: [A]) -> [OneOf, C>] { buildPartialBlock(accumulated: [] as [OneOf], next: a).map { .a($0) } } // matches B of OneOf, C> static func buildPartialBlock(accumulated abc: [OneOf, C>], next b: [B]) -> [OneOf, C>] { buildPartialBlock(accumulated: [] as [OneOf], next: b).map { .a($0) } } // matches C of OneOf, C> static func buildPartialBlock(accumulated abc: [OneOf, C>], next c: [C]) -> [OneOf, C>] { abc + c.map { .b($0) } } // matches A of OneOf, OneOf> static func buildPartialBlock(accumulated abcd: [OneOf, OneOf>], next a: [A]) -> [OneOf, OneOf>] { buildPartialBlock(accumulated: [] as [OneOf], next: a).map { .a($0) } } // matches B of OneOf, OneOf> static func buildPartialBlock(accumulated abcd: [OneOf, OneOf>], next b: [B]) -> [OneOf, OneOf>] { buildPartialBlock(accumulated: [] as [OneOf], next: b).map { .a($0) } } // matches C of OneOf, OneOf> static func buildPartialBlock(accumulated abcd: [OneOf, OneOf>], next c: [C]) -> [OneOf, OneOf>] { buildPartialBlock(accumulated: [] as [OneOf], next: c).map { .b($0) } } // matches D of OneOf, OneOf> static func buildPartialBlock(accumulated abcd: [OneOf, OneOf>], next d: [D]) -> [OneOf, OneOf>] { buildPartialBlock(accumulated: [] as [OneOf], next: d).map { .b($0) } } // non-matching types static func buildPartialBlock(accumulated c0: [C0], next c1: [C1]) -> [OneOf] { c0.map({ OneOf.a($0) }) + c1.map({ OneOf.b($0) }) } // static func buildBlock(_ c: [C]...) -> [C] { // c.flatMap { $0 } // } // // Same type buildBlocks. This works but buildBlock(_ c: [C]...) -> [C] confuses the compiler static func buildBlock (_ c0: [C0], _ c1: [C0]) -> [C0] { [c0, c1].flatMap { $0 } } static func buildBlock (_ c0: [C0], _ c1: [C0], _ c2: [C0]) -> [C0] { [c0, c1, c2].flatMap { $0 } } static func buildEither(first c0: [C0]) -> [OneOf] { c0.map { OneOf.a($0) } } static func buildEither(second c1: [C1]) -> [OneOf] { c1.map { OneOf.b($0) } } static func buildOptional(_ c: [C]?) -> [C] { c ?? [] } static func buildArray(_ c: [[C]]) -> [C] { c.flatMap { $0 } } static func buildExpression(_ node: N) -> [N] { return [node] } static func buildExpression(_ nodeList: NL) -> [NL.Element] { return Array(nodeList) } }