[英]Scalaz validation with Argonaut
我有一个案例类和同伴对象:
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并以列表形式返回Person或一些错误。 所以我需要:
我想以某种形式返回错误,我可以将其转换为更多的JSON,例如:
{
errors: ["Error1", "Error2"]
}
我首先尝试使用Argonauts的encodeValidation方法,该方法返回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
之前(String, Int)
将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
字段的值是数字并且age
是1
,那么您只会得到一个错误( name
one)。 在这种情况下使错误累积有效得多。
相关地,您还会在Validation
上看到关于flatMap
的弃用警告,可以将其视为提醒,不会在绑定期间发生累积。 您可以通过导入scalaz.Validation.FlatMap._
告诉编译器您了解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.