我有一个JSON,可以通过时间和使用的情况下更改类可能是unconvenient,因为我需要每次改变它的结构的JSON变化.
例如,如果我有这样的JSON:
val json= """{
"accounts": [
{ "emailAccount": {
"accountName": "YMail",
"username": "USERNAME",
"password": "PASSWORD",
"url": "imap.yahoo.com",
"minutesBetweenChecks": 1,
"usersOfInterest": ["barney", "betty", "wilma"]
}},
{ "emailAccount": {
"accountName": "Gmail",
"username": "USER",
"password": "PASS",
"url": "imap.gmail.com",
"minutesBetweenChecks": 1,
"usersOfInterest": ["pebbles", "bam-bam"]
}}
]
}"""
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方式访问它:
val parsedJSON = parse(json)
parsedJSON.accounts(0).emailAccount.accountName
Run Code Online (Sandbox Code Playgroud) 当使用circe对Json进行编码时,我们真的希望该type字段显示为例如
scala> val fooJson = foo.asJson
fooJson: io.circe.Json =
{
"this_is_a_string" : "abc",
"another_field" : 123,
"type" : "Foo"
}
Run Code Online (Sandbox Code Playgroud)
这取自之前提到您可以像下面这样配置编码的发行说明:
implicit val customConfig: Configuration =
Configuration.default.withSnakeCaseKeys.withDefaults.withDiscriminator("type")
Run Code Online (Sandbox Code Playgroud)
也谈瑟茜其他信息在这里表明,如果没有任何配置,你应该得到的编码JSON一些类的类型信息.
我错过了什么吗?你如何得到类型显示?
我试图将以下JSON表示为Scala案例类:
{
"cars": {
"THIS IS A DYNAMIC KEY 1": {
"name": "bla 1",
},
"THIS IS A DYNAMIC KEY 2": {
"name": "bla 2",
}
...
}
Run Code Online (Sandbox Code Playgroud)
但是,我的JSON有动态密钥,我在运行时不会知道,我想使用circe来编码/解码.我正在使用正确的方法来使用Scala表示这个?
import io.circe.generic.JsonCodec
@JsonCodec
case class Cars(cars: List[Car])
@JsonCodec
case class Car(whatShouldThisBe: CarDetails) // Not sure how to represent this?
@JsonCodec
case class CarDetails(name: String)
Run Code Online (Sandbox Code Playgroud) 我期待为以下案例类提供JSON编码器:
import io.circe.generic.extras.Configuration
final case class Hello[T](
source: String,
version: Int = 1,
data: T
)
object Hello {
implicit val configuration: Configuration = Configuration.default.withDefaults
}
Run Code Online (Sandbox Code Playgroud)
我通常会叫deriveEncoder[A]的同伴对象,但因为没有参考或已经不在这里工作Encoder了T这里.
该Hello类型将作为库提供给客户端,因此我希望在此类型中尽可能多地使用样板,而不是依赖于提供编码器和解码器的客户端代码.是否有一个惯用的解决方案与circe,以便客户端提供编码器/解码器T,这用于导出编码器/解码器Hello[T]?
使用build.sbt文件,如:
ThisBuild / organization := "com.company"
ThisBuild / version := "1.0.0-SNAPSHOT"
ThisBuild / scalaVersion := "2.11.12"
Global / concurrentRestrictions += Tags.limit(Tags.Test, 1)
Global / scalacOptions ++= Seq("-Ypartial-unification",
"-unchecked",
"-Xfatal-warnings",
"-Ywarn-dead-code",
"-Ywarn-inaccessible",
"-Ywarn-unused",
"-Ywarn-unused-import",
"-Ywarn-macros:after")
Run Code Online (Sandbox Code Playgroud)
我[error] bad option: '-Ywarn-macros:none'跑完了sbt clean compile
如果没有-Ywarn-macros:after,未使用的导入警告会在使用Circe宏的文件中引发虚假警告,例如:import io.circe.{ Decoder, Encoder }.
我阅读了使用Circe Optics的Circe文档给出的示例。文档中的示例非常简单,因为到节点的路径很容易找到。
在我的情况下,json看起来像
import io.circe._, io.circe.parser._
val json = """[["a",{"entity":["foo"]}],["b",{"entity":["bar"]}]]"""
Run Code Online (Sandbox Code Playgroud)
这是有效的json,我可以解析使用 parse(json)
但是,我该如何编写镜头以便提取所有“ foo”,“ bar”。
A 和我正在与 circe 一起做一些工作来编码/解码一些 ADT,我们遇到了一些我们根本不了解的功能。circe 文档中给出的示例按预期工作,但在深入研究后 - 不清楚解码示例为何有效,因此我们很难推理如何在需要时进行修改。
功能(来自关于 ADT 的 Circe 示例):
import cats.syntax.functor._
import io.circe.{ Decoder, Encoder }, io.circe.generic.auto._
import io.circe.syntax._
object GenericDerivation {
// Encoder Redacted
implicit val decodeEvent: Decoder[Event] =
List[Decoder[Event]](
Decoder[Foo].widen,
Decoder[Bar].widen,
Decoder[Baz].widen,
Decoder[Qux].widen
).reduceLeft(_ or _)
}
Run Code Online (Sandbox Code Playgroud)
我明白了 - 基本上从这个列表中选择第一个有效的解码器 - 有道理但是(!)
or似乎是一个采用按名称参数的一元函数。类型签名是:
final def or[AA >: A](d: => Decoder[AA]): Decoder[AA]
并且reduceLeft(来自 IterableOnce)需要一个二元函数。类型签名是:
def reduceLeft[B >: A](op: (B, A) => B): B
然后我的脑袋爆炸了。我显然错过了一些东西,无法弄清楚。
该示例绝对适用于转换 ADT。鉴于该or函数似乎没有满足所需的类型,为什么/如何工作reduceLeft?
我正在尝试使用 doobie、http4s 和 circe 设置一个带有数据库的简单 scala 应用程序。
如何将 java.util.UUID 转换为 doobie.syntax.SqlInterpolator.SingleFragment ?
final case class User(id: UUID, details: UserDetails)
Run Code Online (Sandbox Code Playgroud)
implicit val userDecoder: Decoder[User] = deriveDecoder[User]
implicit def userEntityDecoder[F[_]: Sync]: EntityDecoder[F, User] = jsonOf
implicit val userEncoder: Encoder[User] = deriveEncoder[User]
implicit def userEntityEncoder[F[_]: Applicative]: EntityEncoder[F, User] = jsonEncoderOf
implicit val put: Put[User] =
Put[Json].contramap(_.asJson)
implicit val get: Get[User] =
Get[Json].temap(_.as[User].left.map(_.show))
Run Code Online (Sandbox Code Playgroud)
[info] welcome to sbt 1.3.12 (N/A Java 14.0.1)
[info] loading global plugins from /Users/ryan/.sbt/1.0/plugins
[info] loading settings for project bobbymoore-build from …Run Code Online (Sandbox Code Playgroud) 我是 Scala 新手,正在使用它circe来建模和序列化一些 API 响应。我发现自己使用以下样板
sealed trait SomeTrait
object SomeTrait {
implicit val someEncoder: Encoder[SomeTrait] = deriveEncoder[SomeTrait]
implicit val someDecoder: Decoder[SomeTrait] = deriveDecoder[SomeTrait]
<code>
}
Run Code Online (Sandbox Code Playgroud)
相反,我想使用泛型,并定义类似的东西
trait SerializableTrait[A] {
implicit val someEncoder: Encoder[A] = deriveEncoder[A]
implicit val someDecoder: Decoder[A] = deriveDecoder[A]
}
Run Code Online (Sandbox Code Playgroud)
然后多次使用扩展:
sealed trait SomeTrait
object SomeTrait extends SerializableTrait[SomeTrain] {
<code>
}
Run Code Online (Sandbox Code Playgroud)
但我得到的could not find Lazy implicit value of type io.circe.generic.encoding.DerivedAsObjectEncoder解码器也是类似的。
我知道我可能正在尝试实现circle.auto功能,但我想了解这种用法有什么问题。理想情况下,我希望编译器dervieEncoder/Decoder仅在实际需要时在非类型参数化特征内评估。
我有一个case类,每个字段都是可选的,例如:
case class Foo(name: Option[String],
phone: Option[String],
email: Option[String])
Run Code Online (Sandbox Code Playgroud)
我试图为我的案例类创建手动解码器,发现解码器类似于:
implicit val decoder: Decoder[Foo] = (c: HCursor) => {
for {
name <- c.downField("name").as[String]
phone <- c.downField("phone").as[String]
email <- c.downField("email").as[String]
} yield {
new Foo(name, phone, email)
}
}
Run Code Online (Sandbox Code Playgroud)
但检查downField方法是,如果未设置该字段,则光标将移至FailedCursor,因此会出现错误。
我如何期望某个字段为可选字段,None如果未定义则返回?