J'ai écrit une dérivation automatique de classe de type afin de générer automatiquement un mappage JSS élastique pour les classes de cas. Pour cela, j'utilise la classe de type TypeClass dans Shapeless. Le problème que j'ai est que de nombreux champs dans les classes de cas que nous utilisons sont des énumérations Scala. Par exempleDérivation automatique de classe de type pour les classes de cas avec les champs Scala Enumeration
object ConnectionState extends Enumeration {
type ConnectionState = Value
val ordering, requested, pending, available, down, deleting, deleted, rejected = Value
}
Ou
object ProductCodeType extends Enumeration {
type ProductCodeType = Value
val devpay, marketplace = Value
}
Il semble que je dois définir une instance implicite spécifique pour chaque Enumeration qui est défini afin que la dérivation automatique ramasser (par exemple pour les ConnectionState
et ProductCodeType
). Je ne peux pas avoir un implicit def
pour Enumeration tels que
implicit def enumerationMapping: MappingEncoder[Enumeration] = new MappingEncoder[Enumeration] {
def toMapping = jSingleObject("type", jString("text"))
}
qui fonctionnera pour tous les types d'énumération. J'ai essayé de faire la covariance de classe de type, et un tas d'autres choses mais rien n'a aidé. Des idées?
Voici le code de dérivation:
object Mapping {
trait MappingEncoder[T] {
def toMapping: Json
}
object MappingEncoder extends LabelledProductTypeClassCompanion[MappingEncoder] {
implicit val stringMapping: MappingEncoder[String] = new MappingEncoder[String] {
def toMapping = jSingleObject("type", jString("text"))
}
implicit val intMapping: MappingEncoder[Int] = new MappingEncoder[Int] {
def toMapping = jSingleObject("type", jString("integer"))
}
implicit def seqMapping[T: MappingEncoder]: MappingEncoder[Seq[T]] = new MappingEncoder[Seq[T]] {
def toMapping = implicitly[MappingEncoder[T]].toMapping
}
implicit def optionMapping[T: MappingEncoder]: MappingEncoder[Option[T]] = new MappingEncoder[Option[T]] {
def toMapping = implicitly[MappingEncoder[T]].toMapping
}
object typeClass extends LabelledProductTypeClass[MappingEncoder] {
def emptyProduct = new MappingEncoder[HNil] {
def toMapping = jEmptyObject
}
def product[F, T <: HList](name: String, sh: MappingEncoder[F], st: MappingEncoder[T]) = new MappingEncoder[F :: T] {
def toMapping = {
val head = sh.toMapping
val tail = st.toMapping
(name := head) ->: tail
}
}
def project[F, G](instance: => MappingEncoder[G], to: F => G, from: G => F) = new MappingEncoder[F] {
def toMapping = jSingleObject("properties", instance.toMapping)
}
}
}
}