我试图基于Circe's documentation编写一些代码,但是,尝试同时编译编码器和解码器会导致错误。
如果您想查看整个项目,可以在github(link to the file I have issues with)上这样做
解码器
尝试编译以下代码:
package model
import java.time.LocalDateTime
import cats.effect.IO
import cats.syntax.functor._
import io.circe.generic.auto._
import io.circe.syntax._
import io.circe.{Decoder, Encoder}
import org.http4s.EntityDecoder
import org.http4s.circe.jsonOf
package object account {
sealed trait AccountStatus
case object Onboarding extends AccountStatus
case object SubmissionFailed extends AccountStatus
case object Submitted extends AccountStatus
case object AccountUpdated extends AccountStatus
case object ApprovalPending extends AccountStatus
case object Active extends AccountStatus
case object Rejected extends AccountStatus
object AccountStatus {
implicit val accountStatusEncoder: Encoder[AccountStatus] = Encoder.instance {
case onboarding@Onboarding => onboarding.asJson
case submissionFailed@SubmissionFailed => submissionFailed.asJson
case submitted@Submitted => submitted.asJson
case accountUpdated@AccountUpdated => accountUpdated.asJson
case approvalPending@ApprovalPending => approvalPending.asJson
case active@Active => active.asJson
case rejected@Rejected => rejected.asJson
}
implicit val accountStatusDecoder: Decoder[AccountStatus] =
List[Decoder[AccountStatus]](
Decoder[Onboarding].widen,
Decoder[SubmissionFailed].widen,
Decoder[Submitted].widen,
Decoder[AccountUpdated].widen,
Decoder[ApprovalPending].widen,
Decoder[Active].widen,
Decoder[Rejected].widen
).reduceLeft(_ or _)
implicit val AccountStatusEntityDecoder = jsonOf[IO, AccountStatus]
}
case class Account(
id: String,
status: AccountStatus,
currency: String,
buyingPower: Double,
cash: Double,
cashWithdrawable: Double,
portfolioValue: Double,
patternDayTrader: Boolean,
tradingBlocked: Boolean,
transfersBlocked: Boolean,
accountBlocked: Boolean,
createdAt: LocalDateTime
)
object Account {
implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
}
}
导致以下错误:
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:38:19: not found: type Onboarding
[error] Decoder[Onboarding].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:39:19: not found: type SubmissionFailed
[error] Decoder[SubmissionFailed].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:40:19: not found: type Submitted
[error] Decoder[Submitted].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:41:19: not found: type AccountUpdated
[error] Decoder[AccountUpdated].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:42:19: not found: type ApprovalPending
[error] Decoder[ApprovalPending].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:43:19: not found: type Active
[error] Decoder[Active].widen,
[error] ^
[error] /home/tom/code/scalpaca/src/main/scala/model/account.scala:44:19: not found: type Rejected
[error] Decoder[Rejected].widen
[error] ^
[error] 7 errors found
我发现这很令人困惑,因为编译器抱怨的类型在范围上非常清楚,至少据我所知。
编码器
删除解码器,与之相关的AccountStatusEntityDecoder和account中的AccountStatus字段,并保留以下内容
package model
import java.time.LocalDateTime
import cats.effect.IO
import cats.syntax.functor._
import io.circe.generic.auto._
import io.circe.syntax._
import io.circe.{Decoder, Encoder}
import org.http4s.EntityDecoder
import org.http4s.circe.jsonOf
package object account {
sealed trait AccountStatus
case object Onboarding extends AccountStatus
case object SubmissionFailed extends AccountStatus
case object Submitted extends AccountStatus
case object AccountUpdated extends AccountStatus
case object ApprovalPending extends AccountStatus
case object Active extends AccountStatus
case object Rejected extends AccountStatus
object AccountStatus {
implicit val accountStatusEncoder: Encoder[AccountStatus] = Encoder.instance {
case onboarding@Onboarding => onboarding.asJson
case submissionFailed@SubmissionFailed => submissionFailed.asJson
case submitted@Submitted => submitted.asJson
case accountUpdated@AccountUpdated => accountUpdated.asJson
case approvalPending@ApprovalPending => approvalPending.asJson
case active@Active => active.asJson
case rejected@Rejected => rejected.asJson
}
}
case class Account(
id: String,
currency: String,
buyingPower: Double,
cash: Double,
cashWithdrawable: Double,
portfolioValue: Double,
patternDayTrader: Boolean,
tradingBlocked: Boolean,
transfersBlocked: Boolean,
accountBlocked: Boolean,
createdAt: LocalDateTime
)
object Account {
implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
}
}
我再次收到一些警告和错误:
[info] Compiling 1 Scala source to /home/tom/code/scalpaca/target/scala-2.12/classes ...
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:27:48: match may not be exhaustive.
[warn] It would fail on the following input: Onboarding
[warn] case onboarding@Onboarding => onboarding.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:28:66: match may not be exhaustive.
[warn] It would fail on the following input: SubmissionFailed
[warn] case submissionFailed@SubmissionFailed => submissionFailed.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:29:45: match may not be exhaustive.
[warn] It would fail on the following input: Submitted
[warn] case submitted@Submitted => submitted.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:30:60: match may not be exhaustive.
[warn] It would fail on the following input: AccountUpdated
[warn] case accountUpdated@AccountUpdated => accountUpdated.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:31:63: match may not be exhaustive.
[warn] It would fail on the following input: ApprovalPending
[warn] case approvalPending@ApprovalPending => approvalPending.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:32:36: match may not be exhaustive.
[warn] It would fail on the following input: Active
[warn] case active@Active => active.asJson
[warn] ^
[warn] /home/tom/code/scalpaca/src/main/scala/model/account.scala:33:42: match may not be exhaustive.
[warn] It would fail on the following input: Rejected
[warn] case rejected@Rejected => rejected.asJson
[warn] ^
[error] Error while emitting account.scala
[error] assertion failed:
[error] Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Onboarding$; - account.scala
[error] while compiling: /home/tom/code/scalpaca/src/main/scala/model/account.scala
[error] during phase: jvm
[error] library version: version 2.12.8
[error] compiler version: version 2.12.8
[error] reconstructed args: -bootclasspath /home/tom/jdk1.8.0_201/jre/lib/resources.jar:/home/tom/jdk1.8.0_201/jre/lib/rt.jar:/home/tom/jdk1.8.0_201/jre/lib/sunrsasign.jar:/home/tom/jdk1.8.0_201/jre/lib/jsse.jar:/home/tom/jdk1.8.0_201/jre/lib/jce.jar:/home/tom/jdk1.8.0_201/jre/lib/charsets.jar:/home/tom/jdk1.8.0_201/jre/lib/jfr.jar:/home/tom/jdk1.8.0_201/jre/classes:/home/tom/.ivy2/cache/org.scala-lang/scala-library/jars/scala-library-2.12.8.jar -Ypartial-unification -classpath /home/tom/code/scalpaca/target/scala-2.12/classes:/home/tom/.ivy2/cache/io.circe/circe-generic_2.12/jars/circe-generic_2.12-0.11.1.jar:/home/tom/.ivy2/cache/io.circe/circe-parser_2.12/jars/circe-parser_2.12-0.11.1.jar:/home/tom/.ivy2/cache/io.circe/circe-java8_2.12/jars/circe-java8_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.http4s/http4s-circe_2.12/jars/http4s-circe_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-dsl_2.12/jars/http4s-dsl_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-blaze-client_2.12/jars/http4s-blaze-client_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/com.chuusai/shapeless_2.12/bundles/shapeless_2.12-2.3.3.jar:/home/tom/.ivy2/cache/io.circe/circe-jawn_2.12/jars/circe-jawn_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.http4s/http4s-jawn_2.12/jars/http4s-jawn_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-client_2.12/jars/http4s-client_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/http4s-blaze-core_2.12/jars/http4s-blaze-core_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/io.circe/circe-core_2.12/jars/circe-core_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.typelevel/macro-compat_2.12/jars/macro-compat_2.12-1.1.1.jar:/home/tom/.ivy2/cache/org.typelevel/jawn-parser_2.12/jars/jawn-parser_2.12-0.14.1.jar:/home/tom/.ivy2/cache/org.http4s/jawn-fs2_2.12/jars/jawn-fs2_2.12-0.13.0.jar:/home/tom/.ivy2/cache/org.http4s/http4s-core_2.12/jars/http4s-core_2.12-0.20.0-M4.jar:/home/tom/.ivy2/cache/org.http4s/blaze-http_2.12/jars/blaze-http_2.12-0.14.0-M11.jar:/home/tom/.ivy2/cache/io.circe/circe-numbers_2.12/jars/circe-numbers_2.12-0.11.1.jar:/home/tom/.ivy2/cache/org.spire-math/jawn-parser_2.12/jars/jawn-parser_2.12-0.13.0.jar:/home/tom/.ivy2/cache/org.http4s/parboiled_2.12/jars/parboiled_2.12-1.0.0.jar:/home/tom/.ivy2/cache/co.fs2/fs2-io_2.12/jars/fs2-io_2.12-1.0.2.jar:/home/tom/.ivy2/cache/org.eclipse.jetty.alpn/alpn-api/jars/alpn-api-1.1.3.v20160715.jar:/home/tom/.ivy2/cache/com.twitter/hpack/jars/hpack-1.0.2.jar:/home/tom/.ivy2/cache/org.http4s/blaze-core_2.12/jars/blaze-core_2.12-0.14.0-M11.jar:/home/tom/.ivy2/cache/org.log4s/log4s_2.12/jars/log4s_2.12-1.6.1.jar:/home/tom/.ivy2/cache/co.fs2/fs2-core_2.12/jars/fs2-core_2.12-1.0.2.jar:/home/tom/.ivy2/cache/org.typelevel/cats-effect_2.12/jars/cats-effect_2.12-1.1.0.jar:/home/tom/.ivy2/cache/org.slf4j/slf4j-api/jars/slf4j-api-1.7.25.jar:/home/tom/.ivy2/cache/org.scodec/scodec-bits_2.12/jars/scodec-bits_2.12-1.1.7.jar:/home/tom/.ivy2/cache/org.typelevel/cats-core_2.12/jars/cats-core_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/cats-kernel_2.12/jars/cats-kernel_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/cats-macros_2.12/jars/cats-macros_2.12-1.5.0.jar:/home/tom/.ivy2/cache/org.typelevel/machinist_2.12/jars/machinist_2.12-0.6.6.jar:/home/tom/.ivy2/cache/org.scala-lang/scala-reflect/jars/scala-reflect-2.12.6.jar
[error]
[error] last tree to typer: TypeTree(trait Decoder)
[error] tree position: line 53 of /home/tom/code/scalpaca/src/main/scala/model/account.scala
[error] tree tpe: io.circe.Decoder
[error] symbol: abstract trait Decoder in package circe
[error] symbol definition: abstract trait Decoder extends Serializable (a ClassSymbol)
[error] symbol package: io.circe
[error] symbol owners: trait Decoder
[error] call site: constructor package$Account$anon$importedDecoder$macro$28$1$anon$macro$25$1 in package account
[error]
[error] == Source file context for tree position ==
[error]
[error] 50 )
[error] 51
[error] 52 object Account {
[error] 53 implicit val AccountDecoder: EntityDecoder[IO, Account] = jsonOf[IO, Account]
[error] 54 }
[error] 55
[error] 56 }
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$SubmissionFailed$; - account.scala
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Submitted$; - account.scala
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$AccountUpdated$; - account.scala
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$ApprovalPending$; - account.scala
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Active$; - account.scala
[error] Error while emitting account.scala
[error] assertion failed: Cannot emit primitive conversion from Lmodel/account/package$AccountStatus; to Lmodel/account/package$Rejected$; - account.scala
[warn] 7 warnings found
[error] 7 errors found
我不知道为什么帐户受到影响。 如果我完全删除AccountStatus伴随对象,则我的项目会编译。
我希望获得一些帮助,以消除这些错误,您的输入仍然会受到赞赏。谢谢
答案 0 :(得分:1)
为以后可能会遇到此问题的人提供完整的答案:
stsatlantis的建议确实解决了一个问题(感谢您的评论!),而另一个问题可以通过稍微修改accountStatusEncoder来解决。一种替代解决方案是在ADT中使用案例类,但是,如果您已经有案例对象,则可能是因为它们更适合您的需求/领域。
我最终所做的更改:
object AccountStatus {
implicit val accountStatusEncoder: Encoder[AccountStatus] =
Encoder.instance {
status => status match {
case Onboarding => status.asJson
case SubmissionFailed => status.asJson
case Submitted => status.asJson
case AccountUpdated => status.asJson
case ApprovalPending => status.asJson
case Active => status.asJson
case Rejected => status.asJson
}
}
implicit val accountStatusDecoder: Decoder[AccountStatus] =
List[Decoder[AccountStatus]](
Decoder[Onboarding.type].widen,
Decoder[SubmissionFailed.type].widen,
Decoder[Submitted.type].widen,
Decoder[AccountUpdated.type].widen,
Decoder[ApprovalPending.type].widen,
Decoder[Active.type].widen,
Decoder[Rejected.type].widen
).reduceLeft(_ or _)
implicit val AccountStatusEntityDecoder = jsonOf[IO, AccountStatus]
}