2016-12-07 1 views
2

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) 
     } 
     } 
    } 
    } 

Répondre

0

j'ai pu résoudre le problème en ajoutant defs implicites supplémentaires à la portée:

implicit def enumerationMapping[T <: Enumeration#Value]: MappingEncoder[T] = new MappingEncoder[T] { 
    def toMapping = jSingleObject("type", jString("text")) 
} 
implicit def enumerationSeqMapping[T <: Enumeration#Value]: MappingEncoder[Seq[T]] = new MappingEncoder[Seq[T]] { 
    def toMapping = jSingleObject("type", jString("text")) 
} 

La deuxième implicite était nécessaire que certaines des classes de cas avait des membres de type Seq [T] où T est un type d'énumération.