将验证约束与解组分开

Separating validation constraints from unmarshalling

我遇到了这个 article,它演示了新的游戏验证 API 与 shapeless 的结合。虽然我无法重新创建代码片段(可能是因为我不知道从哪里导入)。

import play.api.libs.json._
import play.api.data.mapping._
import play.api.data.mapping.json._
import shapeless.ops.zipper._

case class User( email: String, password: String )

val reads = Rule.gen[JsValue, User]

// This line is based on code of the article but I'm not sure how to implement it
val validation = Get{ __ =>
  ( __ \ 'email ).read( email )
}

( reads compose validation ).validate( ... )

如何正确创建Get实例?正如文章所暗示的那样,这种方法与无形镜片有什么关系?

我是博客 post 的作者。这是我刚写的完整代码。您将需要验证实验,以便您可以将 repo 和 sbt 控制台克隆到项目中,或者将依赖项添加到您的项目中。我不久前写了这篇文章,所以它依赖于一个相当旧的 shapeless 版本。

import play.api.data.mapping._
import shapeless._

case class ContactInformation(
  label: String,
  email: String,
  phones: Seq[String])

case class Contact(
  firstname: String,
  lastname: String,
  age: Int,
  informations: Seq[ContactInformation])

object Rules extends GenericRules
import Rules._

val contactInfoG = Get[ContactInformation]{ __ =>
  (__ \ 'label).read(notEmpty) ~>
  (__ \ 'email).read(email)
}

val contactG = Get[Contact]{ __ =>
  (__ \ 'age).read(min(0)) ~>
  (__ \ 'informations).read(seqR(contactInfoG))
}

val contact = Contact("Julien", "Tournay", -1, Seq(ContactInformation("Personal", "not quite what I expected", List("01.23.45.67.89", "98.76.54.32.10"))))
contactG.validate(contact)

与镜头的关系如下。验证旨在使用树状数据结构,如 json 或 xml。它以路径的概念为中心。基本上 API 适用于任何可按路径浏览的数据结构。即给定路径(__\'age),就可以在这个位置获取/插入数据。

Lens 为您提供了方便 API 在 class 情况下执行此操作。所以在幕后,(__ \ 'age).read(min(0)) 将使用 lenses 来访问 Contact class 中的字段 age(并且它是完全类型安全的)。

我没有太多时间知道所以不要犹豫,我会回答 n 一会儿 :)