Open kubukoz opened 6 hours ago
This seems to be doable in userland so maybe I'll try making it first to see if it's even possible with the current API...
ok, hear me out:
type IntersperseStrings[T <: Tuple] <: Tuple =
T match {
case EmptyTuple => String *: EmptyTuple
case (t *: ts) => String *: t *: IntersperseStrings[ts]
}
inline def intersperseStrings[T <: Tuple](t: T, strings: Seq[String]): IntersperseStrings[T] =
inline scala.compiletime.erasedValue[T] match {
case _: EmptyTuple => strings.head *: EmptyTuple
case _: (head *: tail) =>
inline t match {
case v: (`head` *: `tail`) =>
val (h *: t) = v
strings.head *: h *: intersperseStrings(t, strings.tail)
}
}
extension (sc: StringContext) {
inline def nodes[M <: Tuple, E <: HtmlElement[IO]](
arg: M
)(
using Modifier[IO, E, M]
): IntersperseStrings[M] = {
StringContext.checkLengths(arg.toList, sc.parts)
intersperseStrings(arg, sc.parts.map(StringContext.processEscapes))
}
}
def go(myDateSignal: Signal[IO, String], appleCountSignal: Signal[IO, String]) = div(
nodes"today is $myDateSignal and I have $appleCountSignal apples, let me say that again $appleCountSignal apples"
)
def go2(myDateSignal: Signal[IO, String], appleCountSignal: Signal[IO, String]) = div(
nodes"today is $myDateSignal and I have $appleCountSignal apples"
)
Probably missing some edge cases.
Need a special case for a no-tuple scenario. Also, it doesn't work if you actually try to interpolate a tuple :/
nodes"today is ${(myDateSignal, "foo")}"
The interpolator will see this as one tuple of length 2, and there are 2 parts in the StringContext - the length check will fail.
Sometimes you just want to do:
but what you actually have to do is:
Alternatively, I suppose you can combine signals:
but it's still a bit cumbersome, works only with text nodes and will result in the entire text updating, rather than just the small pieces that change.
Perhaps it would make it worth adding an interpolator like
nodes"..."
which will serve as a Modifier-based Show?