如何让 Circe 从枚举中跳过某些值?

How to get Circe to skip certain values from the enumeration?

我们有一个 "enumeration" 像这样:

sealed abstract class StatusEnumeration(val value: String)
case object Status {
  case object Mine extends StatusEnumeration("mine")
  case object Someone extends StatusEnumeration("someone")
  case object Neighbor extends StatusEnumeration("neighbor")
  case object Unknown extends StatusEnumeration("unknown")
}

这个结构是由我们的 domain/needs 决定的。但是,我想将此 StatusEnumeration 转换为输出 JSON,如下所示:

case class Root(status: StatusEnumeration)

我设置了以下隐式编码器,它按预期工作:

implicit val encoder = deriveEnumerationEncoder[StatusEnumeration]

但是,如果 StatusEnumeration 设置为 Status.Unknown 我希望跳过值生成或者只输出一个 null 代替(然后我可以通过 dropNullValues 删除)。我怎么能做这样的事情?是否有可能或者我是否需要重新定义另一组枚举?

到目前为止,当@Alec 也评论说要尝试类似的事情时,这是我正在尝试的:

implicit val encoder = deriveEnumerationEncoder[StatusEnumeration].mapJson(x=>{

    x.asString match {
      case Some("Unknown") => Json.Null
      case Some(s) => Json.fromString(s.toLowerCase) // output expect lowercase - not sure if the consumer is case-sensitive
      case None => Json.Null
    }

  })

这似乎确实按预期工作。这是推荐的方法还是有更好的方法?

还没有尝试编译这个,但是基于 Scaladocs 你应该可以做到:

implicit val encoder = Encoder.encodeOption(deriveEnumerationEncoder[StatusEnumeration])
  .contramap {
    case Unknown => None
    case known => Some(known)
  }

基本上,构造一个编码器 Option[StatusEnumeration],然后将 StatusEnumeration 相应地映射到它上面(我很确定 Option 的编码器将 None 作为 nullSome(x) 作为 x 编码)。