Created
October 18, 2022 15:23
-
-
Save felher/5515eb1124268b0e10eadc78778f49a8 to your computer and use it in GitHub Desktop.
Sum-Type Splitter for Laminar with Exhaustiveness-Checks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.raquo.laminar.api.L.* | |
import scala.deriving.* | |
import scala.compiletime.* | |
object SplitEnum: | |
final case class Splitter[A, Todo <: Tuple, O](sig: Signal[A], keyer: A => Int, handlers: Array[Any => O]): | |
inline def close: Signal[O] = | |
inline erasedValue[Todo] match | |
case _: EmptyTuple.type => | |
sig.splitOne(keyer)((key, _, subSig) => handlers(key)(subSig)) | |
case _: *:[h, t] => | |
error( | |
"You can only close the split after all cases are handled.\nCase " + Util | |
.nameOuter[h] + " is not handled yet.\nAdd another handler with .handle((in: Signal[" + Util | |
.nameOuter[h] + "]) => result))" | |
) | |
def handle[OO >: O](caseHandler: Signal[Tuple.Elem[Todo, 0]] => OO): Splitter[A, Tuple.Drop[Todo, 1], OO] = | |
Splitter(sig, keyer, handlers :+ caseHandler.asInstanceOf) | |
extension [A](sig: Signal[A]) | |
def splitEnum(using mirror: Mirror.SumOf[A]): Splitter[A, mirror.MirroredElemTypes, Nothing] = | |
Splitter(sig, mirror.ordinal, Array.empty) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.quoted.* | |
// Needs to be in an extra files since macros need to be in an extra file | |
object Util: | |
def nameOf[A](using t: Type[A], ctx: Quotes): Expr[String] = Expr(Type.show[A]) | |
inline def nameOuter[A] = ${ nameOf[A] } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment