Pass state to SwitchStore.init view builder (#2029)

* Pass state to `SwitchStore.init` view builder

Rather than rely on many, many overloads of `SwitchStore.init` to
strictly accept only `CaseLet`s and an optional, final `Default` view,
let's introduce a single initializer without constraints that is passed
the current state whenever the case changes. This state can be switched
on and route to the appropriate view via `CaseLet`.

The pros:

  * We get exhaustive switching at compile time.

  * We get more flexibility in the view layer. Previously, any
    customization needed to be pushed into the `CaseLet` builder, but
    now `CaseLet` can freely apply view modifiers.

  * We can deprecate and eventually remove the many, many initializer
    overloads, and hopefully slim down binary size in the process, and
    improve view builder compile times when dealing with `SwitchStore`.
    We can also deprecate and eventually remove `Default`.

The cons:

  * It's slightly more verbose and repetitive. You have a `SwitchStore`
    and then a `switch` inside it with many `case`s with `CaseLet`s
    inside them, and the `case .screen:` is followed by
    `CaseLet(/State.screen, ...)`.

  * One is free to extract the state's associated value(s) and use it to
    render a view, but this view will be inert and will not re-render if
    the value it depends on changes in the store. This can lead to some
    surprises, but we can document against the pattern, and maybe in the
    future we can use something like macros to prevent this from being
    possible.

  * You can still get things wrong if you're not careful: there's
    nothing enforcing that the `case` you switch on is the same case you
    send to `CaseLet`, so `case .screenA: CaseLet(/State.screenB, ...)`
    is possible. While unlikely, it's still a copy-paste error in
    waiting.

* wip

* wip

* wip

* Bump

* fix test

* clean up

* clean up

* clean up

* wip

---------

Co-authored-by: Brandon Williams <mbrandonw@hey.com>
This commit is contained in:
Stephen Celis
2023-04-10 11:37:02 -07:00
committed by GitHub
parent 1152492568
commit 4192a843ee
7 changed files with 982 additions and 445 deletions

File diff suppressed because it is too large Load Diff