gpt4 book ai didi

json - 使用 Play 2.4 中其他属性的依赖关系验证 json 属性

转载 作者:行者123 更新时间:2023-12-04 23:45:01 26 4
gpt4 key购买 nike

我有

case class AclRuleScope(kind: String, value: String)

我想转换 JsonAclRuleScope有限制:
type可能只是:“默认” | “用户” | “组” | “领域”
value如果类型为“用户”,则可能只是电子邮件 | “组”,以及其他情况下的一些字符串

我有对象 ReaderWriter ,但我不明白如何获得 type读取时的值 value :
object AclRuleScope {

implicit val aclRuleScopeRead = (
(__ \ "type").read[String](pattern("^(default|user|group|domain)$".r)) and
(__ \ "value").read[String](
email keepAnd
filter(
ValidationError("error.scope.value")
)( ??? == JsString("user") || ??? == JsString("group")))
)(this.apply _)

}

什么必须在 ???

最佳答案

JsConstraints#filter有以下签名

def filter[A](otherwise: ValidationError)(p: A => Boolean)(implicit reads: Reads[A])

当你写
filter(ValidationError("error.scope.value"))(??? == JsString("user") || ??? == JsString("group")))

代码 (??? == JsString("user") || ??? == JsString("group"))实际上是要过滤的第二个参数,因此它应该是 A => Boolean 的谓词.也因为这是在 email 之后应用的读取的是 Reads[String] , 您的实际 AString所以你应该放弃 JsString .

您可以编写的最小更改是:
implicit val aclRuleScopeRead = (
(__ \ "type").read[String](pattern("^(default|user|group|domain)$".r)) and
(__ \ "value").read[String](
email keepAnd
filter(
ValidationError("error.scope.value")
)(x => x == "user" || x == "group"))
).tupled

我强烈建议您将谓词提取到它自己的方法中:
def isValidEmail: (String) => Boolean = {
x => x == "user" || x == "group"
}

并将您的阅读写为
implicit val aclRuleScopeRead = (
(__ \ "type").read[String](pattern("^(default|user|group|domain)$".r)) and
(__ \ "value").read[String](
email keepAnd filter(ValidationError("error.scope.value"))(isValidEmail))
).tupled

更好的是你可以拥有
val validEmail = email keepAnd filter(ValidationError("error.scope.value"))(isValidEmail))

和写
implicit val aclRuleScopeRead = (
(__ \ "type").read[String](pattern("^(default|user|group|domain)$".r)) and
(__ \ "value").read[String](validEmail)
).tupled

在评论中澄清后,如果类型为“用户”或“组”,则您只想解析电子邮件,否则返回空字符串。

答案接近于 this question 中概述的解决方案
value 的读取字段首先需要检查 type的值 field 。 type 字段上的条件如下所示:

(__\"type").read[String].filter(ValidationError("error.scope.value"))(isEmailType)

其中 isEmailType 定义为
def isEmailType: (String) => Boolean = { x => x == "user" || x == "group" }

这将返回一个读取,给出 JsSuccess如果类型是 usergroup和一个 JsError除此以外。从注释中我们知道,如果类型不是 user,我们应该返回空字符串。或 group ,读取可以变成:
(__ \ "type").read[String]
.filter(ValidationError("error.scope.value"))(isEmailType)
.orElse Reads.pure("")

这是安全的,永远不会返回 JsError .这很好,因为有一个专用的 readstype 上强制执行验证,我们当前正在处理的读取仅作为 value 验证的一部分存在。 .
现在我们需要将读取更改为解析 value如果解析为 JsSuccess :
(__ \ "type").read[String]
.filter(ValidationError("error.scope.value"))(isEmailType)
.flatMap(_ => (__ \ "value").read[String](email))
.orElse Reads.pure("")

使用 flatMap,我们替换了 type通过正确读取 value 读取如果 type阅读是成功的。

关于json - 使用 Play 2.4 中其他属性的依赖关系验证 json 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34262581/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com