Skip to content

Instantly share code, notes, and snippets.

@Narigo
Last active December 15, 2015 16:59
Show Gist options
  • Save Narigo/5293554 to your computer and use it in GitHub Desktop.
Save Narigo/5293554 to your computer and use it in GitHub Desktop.
trait MessageHelpers {
type Validated[T] = Either[List[String], T]
type Decoder[T] = Message[JsonObject] => Validated[T]
def validatedMap[X, Y](v: Validated[X], f: X => Y): Validated[Y] = v match {
case Left(errors) => Left(errors)
case Right(x) => Right(f(x))
}
private def missingField[T](field: String): T => Validated[T] = { maybe =>
maybe match {
case null => Left(List("Field " + field + " missing"))
case sth => Right(sth)
}
}
def rfString(field: String): Decoder[String] =
msg => missingField(field)(msg.body.getString(field))
def rfObject(field: String): Decoder[JsonObject] =
msg => missingField(field)(msg.body.getObject(field))
def getRequiredField[T](a: Decoder[T])(implicit message: Message[JsonObject]): Validated[T] =
a(message)
def getRequiredFields[T1, T2](first: Decoder[T1], second: Decoder[T2])(implicit message: Message[JsonObject]): Either[List[String], Tuple2[T1, T2]] = {
(first(message), second(message)) match {
case (Right(sth1), Right(sth2)) => Right((sth1, sth2))
case (Left(error), Right(_)) => Left(error)
case (Right(_), Left(error)) => Left(error)
case (Left(error1), Left(error2)) => Left(error1 ++ error2)
}
}
def getRequiredFields[T1, T2, T3](a: Decoder[T1], b: Decoder[T2], c: Decoder[T3])(implicit message: Message[JsonObject]): Either[List[String], Tuple3[T1, T2, T3]] = {
val either = getRequiredFields(a, b)
(either, getRequiredField(c)) match {
case (Right(sth1), Right(sth2)) => Right(sth1._1, sth1._2, sth2)
case (Left(error), Right(_)) => Left(error)
case (Right(_), Left(error)) => Left(error)
case (Left(error1), Left(error2)) => Left(error1 ++ error2)
}
}
def example(implicit message: Message[JsonObject]) = {
getRequiredFields(rfString("fieldA"), rfObject("fieldB")) match {
case Left(problems) => println("Errors: " + problems.mkString(", "))
case Right((fieldA, fieldB)) =>
println("got a string: " + fieldA)
println("got an object: " + fieldB.encode())
}
getRequiredFields(rfObject("fieldA"), rfString("fieldB"), rfObject("fieldC")) match {
case Left(problems) => println("Errors: " + problems.mkString(", "))
case Right((fieldA, fieldB, fieldC)) =>
println("got an object: " + fieldA.encode())
println("got a string: " + fieldB)
println("got an object: " + fieldC.encode())
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment