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

时间:2019-05-03 19:59:41

标签: scala circe

我们有一个这样的“枚举”:

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

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

case class Root(status: StatusEnumeration)

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

implicit val encoder = deriveEnumerationEncoder[StatusEnumeration]

但是,如果 if 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
    }

  })

这似乎确实可以预期。是推荐的方法还是有更好的方法?

1 个答案:

答案 0 :(得分:2)

还没有尝试编译它,但是基于Scaladocs,您应该可以:

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

基本上,构造一个编码器Option[StatusEnumeration],然后将StatusEnumeration映射到该编码器上(我很确定Option的编码器会将None设置为nullSome(x)编码为x