通过 Scala 中的特征为枚举对象定义隐式格式
Defining implicit format for Enumeration objects via trait in Scala
我正在尝试为多个对象定义一个隐式特征,以便在反序列化枚举的 JSON 值时使用。我了解如何在一个对象中执行此操作,但我希望将此行为模板化以保持我的代码干燥。我可以通过执行以下操作来完成此操作:
object SomeEnum extends Enumeration {
type SomeEnum = Value
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
implicit object SomeEnumFormat extends Format[SomeEnum] {
def writes(o: SomeEnum): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[SomeEnum] = json match {
case JsString(x) => JsSuccess(SomeEnum.withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}
以下是我一直在尝试的:
object SomeEnum extends Mappable {
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
}
object SomeOtherEnum extends Mappable {
val ABC: SomeOtherEnum = Value("Abc")
val DEF: SomeOtherEnum = Value("Def")
}
trait Mappable extends Enumeration {
implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)
def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)
implicit object someFormat extends Format[Class[_ <: Mappable]] {
def writes(o: Class[_ <: Mappable]): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[Value] = json match {
case JsString(x) => JsSuccess(this.asInstanceOf[Mappable].withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}
我希望继承特征的行为与为 class 扩展特征提供隐式对象的模板版本相同,但我收到以下错误:
found : Mappable#Value
required: Mappable.this.Value
如果我将读取的 return 类型设为 JsResult[Mappable#Value]
代码无法编译,因为没有找到指定枚举类型的隐式声明。任何帮助将不胜感激。
我最初误解了发生的事情,以下是有效的解决方案
object SomeEnum extends Mappable {
type SomeEnum = Value
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
}
object SomeOtherEnum extends Mappable {
type SomeOtherEnum = Value
val ABC: SomeOtherEnum = Value("Abc")
val DEF: SomeOtherEnum = Value("Def")
}
trait Mappable extends Enumeration {
implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)
def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)
implicit object someFormat extends Format[Value] {
def writes(o: Value): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[Value] = json match {
case JsString(x) => JsSuccess(withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}
我正在尝试为多个对象定义一个隐式特征,以便在反序列化枚举的 JSON 值时使用。我了解如何在一个对象中执行此操作,但我希望将此行为模板化以保持我的代码干燥。我可以通过执行以下操作来完成此操作:
object SomeEnum extends Enumeration {
type SomeEnum = Value
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
implicit object SomeEnumFormat extends Format[SomeEnum] {
def writes(o: SomeEnum): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[SomeEnum] = json match {
case JsString(x) => JsSuccess(SomeEnum.withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}
以下是我一直在尝试的:
object SomeEnum extends Mappable {
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
}
object SomeOtherEnum extends Mappable {
val ABC: SomeOtherEnum = Value("Abc")
val DEF: SomeOtherEnum = Value("Def")
}
trait Mappable extends Enumeration {
implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)
def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)
implicit object someFormat extends Format[Class[_ <: Mappable]] {
def writes(o: Class[_ <: Mappable]): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[Value] = json match {
case JsString(x) => JsSuccess(this.asInstanceOf[Mappable].withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}
我希望继承特征的行为与为 class 扩展特征提供隐式对象的模板版本相同,但我收到以下错误:
found : Mappable#Value
required: Mappable.this.Value
如果我将读取的 return 类型设为 JsResult[Mappable#Value]
代码无法编译,因为没有找到指定枚举类型的隐式声明。任何帮助将不胜感激。
我最初误解了发生的事情,以下是有效的解决方案
object SomeEnum extends Mappable {
type SomeEnum = Value
val FIRST: SomeEnum = Value("First")
val SECOND: SomeEnum = Value("Second")
}
object SomeOtherEnum extends Mappable {
type SomeOtherEnum = Value
val ABC: SomeOtherEnum = Value("Abc")
val DEF: SomeOtherEnum = Value("Def")
}
trait Mappable extends Enumeration {
implicit val enumMapper: JdbcType[Value] with BaseTypedType[Value] = MappedColumnType.base[Value,String](_.toString, this.withName)
def unapply[Type](s: String): Option[Value] = values.find(s == _.toString)
implicit object someFormat extends Format[Value] {
def writes(o: Value): JsValue = JsString(o.toString)
def reads(json: JsValue): JsResult[Value] = json match {
case JsString(x) => JsSuccess(withName(x.toLowerCase.capitalize))
case _ => JsError()
}
}
}