CardStackBuilder.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //
  2. // CardStackBuilder.swift
  3. // LoopKitUI
  4. //
  5. // Created by Michael Pangburn on 4/15/20.
  6. // Copyright © 2020 LoopKit Authors. All rights reserved.
  7. //
  8. import SwiftUI
  9. /// Constructs an array of `Card` views from arbitrary `View` instances.
  10. ///
  11. /// A multi-component card can be constructed using one of `Card`'s initializers.
  12. @resultBuilder
  13. public struct CardStackBuilder {
  14. public typealias Component = CardStack
  15. public static func buildIf(_ component: Component?) -> Component {
  16. // If `nil` (i.e. a condition is `false`), leave a placeholder `nil` view to enable smooth insertion when the condition becomes `true`.
  17. component ?? CardStack(cards: [nil])
  18. }
  19. public static func buildBlock<V: View>(_ v: V) -> Component {
  20. toCardStack(v)
  21. }
  22. public static func buildBlock<V0: View, V1: View>(_ v0: V0, _ v1: V1) -> Component {
  23. CardStack(reducing: [toCardStack(v0), toCardStack(v1)])
  24. }
  25. public static func buildBlock<V0: View, V1: View, V2: View>(_ v0: V0, _ v1: V1, _ v2: V2) -> Component {
  26. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2)])
  27. }
  28. public static func buildBlock<V0: View, V1: View, V2: View, V3: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3) -> Component {
  29. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3)])
  30. }
  31. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4) -> Component {
  32. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4)])
  33. }
  34. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View, V5: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5) -> Component {
  35. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4), toCardStack(v5)])
  36. }
  37. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View, V5: View, V6: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6) -> Component {
  38. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4), toCardStack(v5), toCardStack(v6)])
  39. }
  40. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View, V5: View, V6: View, V7: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7) -> Component {
  41. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4), toCardStack(v5), toCardStack(v6), toCardStack(v7)])
  42. }
  43. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View, V5: View, V6: View, V7: View, V8: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7, _ v8: V8) -> Component {
  44. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4), toCardStack(v5), toCardStack(v6), toCardStack(v7), toCardStack(v8)])
  45. }
  46. public static func buildBlock<V0: View, V1: View, V2: View, V3: View, V4: View, V5: View, V6: View, V7: View, V8: View, V9: View>(_ v0: V0, _ v1: V1, _ v2: V2, _ v3: V3, _ v4: V4, _ v5: V5, _ v6: V6, _ v7: V7, _ v8: V8, _ v9: V9) -> Component {
  47. CardStack(reducing: [toCardStack(v0), toCardStack(v1), toCardStack(v2), toCardStack(v3), toCardStack(v4), toCardStack(v5), toCardStack(v6), toCardStack(v7), toCardStack(v8), toCardStack(v9)])
  48. }
  49. // TODO: Simplify using `buildExpression` when Swift 5.2 is available.
  50. private static func toCardStack<V: View>(_ v: V) -> CardStack {
  51. if let stack = v as? CardStack {
  52. return stack
  53. } else if let card = v as? Card {
  54. return CardStack(cards: [card])
  55. } else {
  56. return CardStack(cards: [Card(parts: [AnyView(v)])])
  57. }
  58. }
  59. }