【发布时间】:2017-04-22 22:39:27
【问题描述】:
我已经编写了自动类型类派生,以便为案例类自动生成 elasticsearch Json 映射。 为此,我在无形中使用 TypeClass 类型类。 我遇到的问题是,我们使用的案例类中的许多字段都是 Scala 枚举。 例如
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)
}
}
}
}
【问题讨论】: