[英]Complex Encoding of multiple nested classes using scala argonaut
What is wrong with the MainClassEncodeJson
method below? 下面的
MainClassEncodeJson
方法有什么问题?
Have been following the example for Implicit JSON conversion with Scala http://lollyrock.com/articles/scala-implicit-conversion/ 一直在使用Scala进行隐式JSON转换的示例http://lollyrock.com/articles/scala-implicit-conversion/
This question is similar to: Encoding nested classes using scala argonaut 这个问题类似于: 使用Scala argonaut编码嵌套类
The difference being an additional layer/s of nesting. 区别在于附加的嵌套层。
Am getting the following error from the compiler: 正在从编译器获取以下错误:
Cannot resolve reference EncodeJson with such signature
Thanks for in advance. 预先感谢您。
Have included the Encoder and Decoder for completeness 包括编码器和解码器以确保完整性
object ImplicitConversion {
case class MainClass (txid: String,hat: Hat,version: Int,bot: Bot, time: Int, locktime: Int)
case class Hat (value: Float,n: Int,nxt: Nxt)
case class Nxt (typetx: String,reqsigs: Int,addresses: List[Address])
case class Bot (base: String,sequence: Int)
case class Address (address: String)
// implicit conversion with argonaut
implicit def MainClassEncodeJson: EncodeJson[MainClass] =
EncodeJson((m: MainClass) =>
("txid" := m.txid) ->:
("hat" := Json (
("value" := m.hat.value),
("n" := m.hat.n),
("nxt" := Json (
("typetx" := m.hat.nxt.typetx),
("reqsigs" := m.hat.nxt.reqsigs),
("addresses" := m.hat.nxt.addresses)
)
) ->: jEmptyObject
)
) ->: jEmptyObject
("version" := m.version) ->:
("bot" := Json (
("base" := m.bot.base)
("sequence" := m.bot.sequence)
)
) ->: jEmptyObject
("time" := m.time) ->:
("locktime" := m.locktime) ->:
)
implicit def MainClassDecodeJson: DecodeJson[MainClass] =
DecodeJson(c => for {
txid <- (c --\ "txid").as[String]
hat <- (c --\ "hat").as[Json]
version <- (c --\ "version").as[Int]
bot <- (c --\ "bot").as[Json]
time <- (c --\ "time").as[Int]
locktime <- (c --\ "locktime").as[Int]
// extract data from hat
value <- (hat.acursor --\ "value").as[Float]
n <- (hat.acursor --\ "n").as[Int]
nxt <- (hat.acursor --\ "nxt").as[Json]
// extract data from nxt
typetx <- (nxt.acursor --\ "typetx").as[String]
reqsigs <- (nxt.acursor --\ "reqsigs").as[Int]
addresses <- (nxt.acursor --\ "addresses").as[List[Address]]
// extract data from bot
base <- (bot.acursor --\ "base").as[String]
sequence <- (bot.acursor --\ "sequence").as[Int]
} yield MainClass(txid, hat(value, n, Nxt(typetx, reqsigs, addresses)),
version, Bot(base, sequence), time, locktime)
}
Using version 6.1 with Scalaz 7.1.x I got the following to compile using the CodecJson\\[_\\]
and casecodecN
functions. 在Scalaz 7.1.x中使用6.1版时,我得到了以下内容,可以使用
CodecJson\\[_\\]
和casecodecN
函数进行编译。
import scalaz._, Scalaz._
import argonaut._, Argonaut._
object ImplicitConversion {
case class MainClass( txid: String
, hat: Hat
, version: Int
, bot: Bot
, time: Int
, locktime: Int)
case class Hat( value: Float
, n: Int
, nxt: Nxt)
case class Nxt( typetx: String
, reqsigs: Int
, addresses: List[Address])
case class Bot( base: String
, sequence: Int)
case class Address(address: String)
implicit val botCodec: CodecJson[Bot] =
casecodec2(Bot.apply, Bot.unapply)("base", "sequence")
implicit val addressCodec: CodecJson[Address] =
casecodec1(Address.apply, Address.unapply)("address")
implicit val nxtCodec: CodecJson[Nxt] =
casecodec3(Nxt.apply, Nxt.unapply)("typetx", "reqsigs", "addresses")
implicit val hatCodec: CodecJson[Hat] =
casecodec3(Hat.apply, Hat.unapply)("value", "n", "nxt")
implicit val mainClassCodec: CodecJson[MainClass] =
casecodec6(MainClass.apply, MainClass.unapply)("txid", "hat", "version", "bot", "time", "locktime")
}
My build.sbt
looks like this: 我的
build.sbt
看起来像这样:
name := "stackoverflow"
scalaVersion := "2.11.7"
val scalazVersion = "7.1.0"
val argonautVersion = "6.1"
libraryDependencies ++= Seq(
"org.scalaz" %% "scalaz-core" % scalazVersion,
"io.argonaut" %% "argonaut" % argonautVersion,
)
By using this way of defining the encode/decode - when using simple case classes to embody JSON object literals - I think we end up with simpler code to maintain due to improved readability and reduction of moving parts (it's all declarative as opposed to following the for-comprehension logic). 通过使用这种定义编码/解码的方式-当使用简单的案例类来体现JSON对象文字时-我认为由于可读性的提高和运动部件的减少,我们最终得到了更简单的代码来进行维护(与遵循理解逻辑)。 I also find it is a more composable definition of the problem so I can start out small without worrying about what wraps inner case classes.
我还发现它是问题的更复杂的定义,因此我可以从小处入手,而不必担心包装内部案例类的问题。
You will need to put the CodecJson[_]
implicits in order of need (ie define the inner case class codec implicits before outer ones that use them) or you will get compile-time warnings. 你需要把
CodecJson[_]
implicits 需要的顺序(即使用它们外层标记之前定义的内壳类编解码器implicits),或者你会得到编译时警告。
There is also a helpful example in the QuickStart documentation on the Argonaut website. Argonaut网站上的QuickStart文档中还有一个有用的示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.