如何让 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
作为 null
和 Some(x)
作为 x
编码)。
我们有一个 "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
作为 null
和 Some(x)
作为 x
编码)。