加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – `circe`类型级Json =>一个函数?

发布时间:2020-12-16 18:08:54 所属栏目:安全 来源:网络整理
导读:使用circe或argonaut,我怎么能写一个Json = A(注意 – Json可能不是该类型的名称)其中A由SSN类给出: // A USA Social Security Number has exactly 8 digits. case class SSN(value: Sized[List[Nat],_8]) ? 伪代码: //假设这个函数名为f f(JsArray(JsNum
使用circe或argonaut,我怎么能写一个Json => A(注意 – Json可能不是该类型的名称)其中A由SSN类给出:

// A USA Social Security Number has exactly 8 digits.
  case class SSN(value: Sized[List[Nat],_8])

伪代码:

//假设这个函数名为f

f(JsArray(JsNumber(1)))因为它的大小为1而不能成为A,而

f(JsArray(JsNumber(1),…,JsNumber(8)))=== SSN(SizedList(1,8))

解决方法

circe(当前)没有为Sized提供实例,但它可能应该.在任何情况下,你都可以直截了当地写自己的:

import cats.data.Xor
import io.circe.{ Decoder,DecodingFailure }
import shapeless.{ Nat,Sized }
import shapeless.ops.nat.ToInt
import shapeless.syntax.sized._

implicit def decodeSized[L <: Nat,A](implicit
  dl: Decoder[List[A]],ti: ToInt[L]
): Decoder[Sized[List[A],L]] = Decoder.instance { c =>
  dl(c).flatMap(as =>
    Xor.fromOption(as.sized[L],DecodingFailure(s"Sized[List[A],_${ti()}]",c.history))
  )
}

我已将此限制为List表示,但如果您愿意,可以使其更通用.

现在你可以像这样编写你的SSN实例(请注意,我使用的是Int而不是Nat用于个别数字,因为一旦你得到一些静态类型为Nat的东西,它就不值得了):

case class SSN(value: Sized[List[Int],Nat._8])

implicit val decodeSSN: Decoder[SSN] = Decoder[Sized[List[Int],Nat._8]].map(SSN(_))

然后:

scala> import io.circe.jawn.decode
import io.circe.jawn.decode

scala> decode[SSN]("[1,2,3,4,5,6,7,8]")
res0: cats.data.Xor[io.circe.Error,SSN] = Right(SSN(List(1,8)))

scala> decode[SSN]("[1,7]")
res1: cats.data.Xor[io.circe.Error,SSN] = Left(DecodingFailure(Sized[List[A],_8],List()))

如果你真的想要一个Json => SSN你可以这样做:

val f: Json => SSN = Decoder[SSN].decodeJson(_).valueOr(throw _)

但这并不是对circe的惯用.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读