gpt4 book ai didi

json - 使用 Argonaut 进行 Scalaz 验证

转载 作者:行者123 更新时间:2023-12-04 06:42:04 24 4
gpt4 key购买 nike

我有一个案例类和伴随对象:

case class Person private(name: String, age: Int)

object Person {

def validAge(age: Int) = {
if (age > 18) age.successNel else "Age is under 18".failureNel
}

def validName(name: String) = {
name.successNel
}

def create(name: String, age: Int) = (validAge(age) |@| validName(name))(Person.apply)

}

我想使用 Argonaut 解析一些 JSON 并以列表的形式返回一个人或一些错误。所以我需要:

  1. 从字符串中读取 JSON,并验证字符串的格式是否正确
  2. 将 JSON 解码为人员或错误字符串列表。

我想以某种形式返回错误,我可以将其转换为更多 JSON,例如:

{
errors: ["Error1", "Error2"]
}

我首先尝试使用Argonauts的decodeValidation方法,该方法返回一个Validation[String, X]。不幸的是,我需要一个错误列表。

有什么建议吗?

最佳答案

我将其添加为答案,因为这是我立即解决问题的方法,但我已经有一段时间没有密切关注 Argonaut 的开发了,我很想听听有更好的方法。首先是设置,它修复了您的一些小问题,并添加了名称有效性的条件,以使后面的示例更有趣:

import scalaz._, Scalaz._

case class Person private(name: String, age: Int)

object Person {
def validAge(age: Int): ValidationNel[String, Int] =
if (age > 18) age.successNel else "Age is under 18".failureNel

def validName(name: String): ValidationNel[String, String] =
if (name.size >= 3) name.successNel else "Name too short".failureNel

def create(name: String, age: Int) =
(validName(name) |@| validAge(age))(Person.apply)
}

然后,在创建 Person 之前,我会将 JSON 解码为 (String, Int) 对:

import argonaut._, Argonaut._

def decodePerson(in: String): ValidationNel[String, Person] =
Parse.decodeValidation(in)(
jdecode2L((a: String, b: Int) => (a, b)
)("name", "age")).toValidationNel.flatMap {
case (name, age) => Person.create(name, age)
}

然后:

scala> println(decodePerson("""{ "name": "", "age": 1 }"""))
Failure(NonEmptyList(Name too short, Age is under 18))

请注意,在更复杂的情况下,这不会累积错误 - 例如如果 name 字段的值为数字且 age1,则您只会收到一个错误(name 一)。在这种情况下使错误累积起作用会复杂得多。

相关地,您还会在 Validation 上看到有关 flatMap 的弃用警告,您可以将其视为提醒,不会在绑定(bind)期间发生累积。您可以通过导入 scalaz.Validation.FlatMap._ 来告诉编译器您理解。

关于json - 使用 Argonaut 进行 Scalaz 验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29596564/

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