Created
October 8, 2019 11:09
-
-
Save vaclavsvejcar/dbddce8fa8dfbca0dba6eddc3c5b39bc to your computer and use it in GitHub Desktop.
This file contains hidden or 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 shapeless._ | |
import scala.annotation.implicitNotFound | |
/* | |
* Used type names: | |
* - A = type of the sealed trait | |
* - C = type of the coproduct | |
* - H = type of the iterated singleton (case object) instance | |
* - T = type of the iterated coproduct | |
*/ | |
trait AllSingletons[A, C <: Coproduct] { | |
def values: List[A] | |
} | |
object AllSingletons { | |
implicit def cnilSingletons[A]: AllSingletons[A, CNil] = new AllSingletons[A, CNil] { | |
def values: Nil.type = Nil | |
} | |
implicit def coproductSingletons[A, H <: A, T <: Coproduct]( | |
implicit tail: AllSingletons[A, T], | |
witness: Witness.Aux[H]): AllSingletons[A, H :+: T] = new AllSingletons[A, H :+: T] { | |
def values: List[A] = witness.value :: tail.values | |
} | |
} | |
@implicitNotFound( | |
"Cannot enumerate the ${A} sealed trait. Make sure only case objects extends this trait.") | |
trait EnumCoproduct[A] { | |
/** | |
* Returns all ''case object'' instances for the given ''sealed trait''. If any ''case class'' | |
* extends this sealed trait, this call will end up with compile error. | |
* | |
* @return set of case objects extending sealed trait | |
*/ | |
def values: Set[A] | |
} | |
/** | |
* Utilities allowing to enumerate the case objects of the sealed trait. | |
*/ | |
object EnumCoproduct { | |
implicit def fromAllSingletons[A, C <: Coproduct]( | |
implicit gen: Generic.Aux[A, C], | |
singletons: AllSingletons[A, C]): EnumCoproduct[A] = new EnumCoproduct[A] { | |
def values: Set[A] = singletons.values.toSet | |
} | |
def apply[A](implicit instance: EnumCoproduct[A]): EnumCoproduct[A] = instance | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment