【问题标题】:using enumeratum enum as BSONDocument value does not compile使用 enumeratum 枚举作为 BSONDocument 值无法编译
【发布时间】:2020-11-23 17:09:04
【问题描述】:

当我尝试将我的查询包装在 BSONDocument 中并将我的 enumeratum 枚举作为它解说编译的值时。

例如,我的枚举:

sealed trait ProcessingStatus extends EnumEntry with UpperSnakecase

object ProcessingStatus extends Enum[ProcessingStatus] with ReactiveMongoBsonEnum[ProcessingStatus] {

  val values: IndexedSeq[ProcessingStatus] = findValues

  case object Processing extends ProcessingStatus

  case object Done extends ProcessingStatus

}

我玩了解释如何序列化的 json 序列化程序:

object JsonSerialization {

  import reactivemongo.api.bson._

  implicit object ProcessingStatusReader extends BSONReader[ProcessingStatus] {
    override def readTry(bson: BSONValue): Try[ProcessingStatus] = bson match {
      case BSONString(s) => bson.asTry[ProcessingStatus]
      case _ => Failure(new RuntimeException("String value expected"))
    }
  }

  implicit object ProcessingStatusWriter extends BSONWriter[ProcessingStatus] {
    override def writeTry(t: ProcessingStatus): Try[BSONString] = Try(BSONString(t.entryName))
  }
  //Report Serializers
  implicit val ProcessingStatusFormat: Format[ProcessingStatus] = EnumFormats.formats(ProcessingStatus)
  implicit val ReportFormat: OFormat[Report] = Json.format[Report]
}

现在在我的 dao 中无法编译:

import reactivemongo.play.json.compat.json2bson.{toDocumentReader, toDocumentWriter}
import serializers.JsonSerialization._

    def findReport(reportId: String) = {
      val test = BSONDocument("123" -> ProcessingStatus.Processing) // dosent compile
    }

截图:

编译错误:

overloaded method apply with alternatives:
  (elms: Iterable[(String, reactivemongo.api.bson.BSONValue)])reactivemongo.api.bson.BSONDocument <and>
  (elms: reactivemongo.api.bson.ElementProducer*)reactivemongo.api.bson.BSONDocument
 cannot be applied to ((String, enums.ProcessingStatus.Done.type))
    val test = BSONDocument("status" -> ProcessingStatus.Done)

【问题讨论】:

  • 它是如何工作的? JsonSerialization 不提供 BSONWriter[ProcessingStatus.Processing]{toDocumentReader, toDocumentWriter} 也不提供仅适用于 BSONDocument/OFormat(而不是 Format)。
  • @cchantep 编辑了 JsonSerialization(正如您在问题中所见)我的 BSONWriter/BSONReader,仍然是讲解员的工作。很难找到合适的例子,,,
  • “它不起作用”远不够具体。要获取有关错误的帮助,请粘贴错误详细信息。
  • @cchantep 我在BSONDocument无法编译的问题中写了,我不知道该怎么描述它,如果有帮助,我添加了一个截图。

标签: scala reactivemongo


【解决方案1】:

IDE 错误不是编译错误(建议使用sbt 及其控制台进行测试)。

您的代码(如下所示)编译正常,无论 IDE 告诉什么(这是错误的)。

import reactivemongo.api.bson._
import scala.util.Try

trait ProcessingStatus {
  def entryName = "foo"
}

object JsonSerialization {
  implicit object ProcessingStatusWriter extends BSONWriter[ProcessingStatus] {
    override def writeTry(t: ProcessingStatus): Try[BSONString] = Try(BSONString(t.entryName))
  }
}

import JsonSerialization._

BSON.write(new ProcessingStatus {})

Note.1: writeTry 不会覆盖任何内容,因此修饰符是无用的(并且可能导致误解)。

注 2: Try(..) 具有纯值,例如 BSONString(t.entryName) 是过度设计的,而是使用 Success(..)

注3: 方便的工厂有val w = BSONWriter[T] { t =&gt; ... }等。


编辑:

类型类BSONWriter(与大多数类型类一样)是不变的,因此在隐式范围内拥有BSONWriter[T] 不允许解析BSONWriter[U] forSome { U &lt;: T }

trait ProcessingStatus {
  def entryName: String
}

object ProcessingStatus {
  case object Done extends ProcessingStatus { val entryName = "done" }
}

object JsonSerialization {
  implicit object ProcessingStatusWriter extends BSONWriter[ProcessingStatus] {
    override def writeTry(t: ProcessingStatus): Try[BSONString] = Try(BSONString(t.entryName))
  }
}

import JsonSerialization._

BSON.write(ProcessingStatus.Done
/*
<console>:32: error: could not find implicit value for parameter writer: reactivemongo.api.bson.BSONWriter[ProcessingStatus.Done.type]
       BSON.write(ProcessingStatus.Done)
 */

// --- BUT ---

BSON.write(ProcessingStatus.Done: ProcessingStatus)
// Success(BSONString(done))

在 API 中将 Done(和其他情况)暴露为 ProcessingStatus 也有效。

import reactivemongo.api.bson._
import scala.util.Try

sealed trait ProcessingStatus {
  def entryName: String
}

object ProcessingStatus {
  val Done: ProcessingStatus = new ProcessingStatus { val entryName = "done" }
}

object JsonSerialization {
  implicit object ProcessingStatusWriter extends BSONWriter[ProcessingStatus] {
    override def writeTry(t: ProcessingStatus): Try[BSONString] = Try(BSONString(t.entryName))
  }
}

import JsonSerialization._

BSON.write(ProcessingStatus.Done)

【讨论】:

  • 在题尾添加编译错误
  • BSONWriter 是不变的,拥有BSONWriter[T] 并不意味着你拥有BSONWriter[U &lt;: T]。要么将 Done 暴露为 ProcessingStatus,要么真正使用为这种情况提供 BSON 支持的枚举。
  • “将Done 公开为ProcessingStatus”是什么意思?也试过用枚举支持implicit val reader: BSONReader[ProcessingStatus] = implicitly[BSONReader[ProcessingStatus]],没解决
  • 您在示例中不使用枚举,而是使用对象覆盖处理程序。请先查看枚举示例和文档。
  • 如果您可以发布应该可以工作的代码修复程序,那就太棒了。我查看文档并找不到我需要的东西,或者可能不明白某些东西,这就是我在这里的原因@cchantep
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-18
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-15
相关资源
最近更新 更多