I am trying to write a SwiftUI view that adds a special modifier to the final view inside it. Because I am using SwiftUI, the "shape" of the data coming in is controlled by what is acceptable to return from a @ViewBuilder closure; I specifically don't want to use this to enforce something like "you must always add a particular modifier to the last view or your code won't type check," I want to do this for the consumers of the API internally.
I thought I should be able to do it by writing the following:
func topLevelFunction<each T, U>(t: () -> (repeat each T, U)) {
let result = t()
tupleViewInit(t: (result.0, Decorate(decorated: result.1)))
}
func tupleViewInit<T>(t: T) {
}
struct Decorate<T> {
var decorated: T
}
Unfortunately this fails, the compiler complains that "Value pack expansion can only appear inside a function argument list or tuple element."
Interestingly, this compiles:
func topLevelFunction<each T, U>(t: () -> (repeat each T, U)) {
let result = t()
tupleViewInit(t: result)
}
It feels like parameter packs are "look, don't touch" today, in the sense that I can pass this object around as much as I want, or turn it back into a tuple, but I can't do anything with any of the stuff inside it without losing the information that the last element was of type U.
My other thought was to try to write some function that can take in a whole parameter pack, and somehow understand that I'm at the end, but I can't think of any way to do that.
My final, nuclear option, is to manually grab the memory out of the parameter pack and the last element of the tuple, then rearrange it into something that is what I want, then force cast it back into (repeat each T, Decorated<U>), but this seems like a bad idea on many levels.
Any advice?