2016-12-07 10 views
2

Я написал автоматический вывод класса типа, чтобы автоматически генерировать сопоставление JScript для elasesearch для классов case. Для этого я использую класс типа TypeClass в бесформенном виде. Проблема в том, что многие поля в классах классов, которые мы используем, являются перечислениями Scala. НапримерАвтоматический вывод класса класса для классов классов с полями Scala Enumeration

object ConnectionState extends Enumeration { 
    type ConnectionState = Value 
    val ordering, requested, pending, available, down, deleting, deleted, rejected = Value 
    } 

Или

object ProductCodeType extends Enumeration { 
    type ProductCodeType = Value 
    val devpay, marketplace = Value 
    } 

Кажется, я должен определить конкретный неявное экземпляр для каждого перечисления, определяется в порядке, автоматический вывод заберет ее (например для обоих ConnectionState и ProductCodeType). я не могу иметь один implicit def для Перечисления, таких как

implicit def enumerationMapping: MappingEncoder[Enumeration] = new MappingEncoder[Enumeration] { 
    def toMapping = jSingleObject("type", jString("text")) 
    } 

, которая будет работать для всех типов перечисления. Я пробовал сделать классный класс ковариантным, и куча других вещей, но ничего не помогло. Любые идеи?

Вот код вывода:

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

ответ

0

Я был в состоянии решить эту проблему путем добавления дополнительного неявного DEFS размаха:

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

Второго неявный был необходимо, поскольку некоторые из классов дела имели члены типа Seq [T], где T - некоторый тип перечисления.