Skip to content

Instantly share code, notes, and snippets.

@gbougeard
Created January 23, 2015 23:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gbougeard/33cc4da64b682329412a to your computer and use it in GitHub Desktop.
Save gbougeard/33cc4da64b682329412a to your computer and use it in GitHub Desktop.
Validation tryouts
// I want to parse a json payload to a given type corresponding to an event sent in http headers
// I defined an ADT to modelize the different events
sealed trait GHEvent
object GHEvent extends ADTEnum[GHEvent] {
case object commit_comment extends GHEvent
case object create extends GHEvent
case object delete extends GHEvent
case object deployment extends GHEvent
case object deployment_status extends GHEvent
case object fork extends GHEvent
case object gollum extends GHEvent
case object issue_comment extends GHEvent
case object issues extends GHEvent
case object member extends GHEvent
case object membership extends GHEvent
case object public extends GHEvent
case object pull_request_review_comment extends GHEvent
case object pull_request extends GHEvent
case object push extends GHEvent
case object repository extends GHEvent
case object release extends GHEvent
case object status extends GHEvent
case object team_add extends GHEvent
case object watch extends GHEvent
val list = Seq(
commit_comment ,
create ,
delete ,
deployment ,
deployment_status ,
fork ,
gollum ,
issue_comment ,
issues ,
member ,
membership ,
public ,
pull_request_review_comment ,
pull_request ,
push ,
repository ,
release ,
status ,
team_add ,
watch
)
}
// Using this
// Enum type based on Sum types (OR)
trait ADTEnum[A] {
import play.api.data.mapping._
val list: Seq[A]
def withName(name: String): Option[A] = {
list.find(_.toString.toLowerCase == name.toLowerCase)
}
implicit val rule: Rule[String, A] = Rule.fromMapping {
case str:String =>
withName(str) match {
case Some(name) => Success(name)
case None => Failure(Seq(ValidationError(s"error.unknownADTEnum")))
}
case _ => Failure(Seq(ValidationError(s"error.ADTEnumMustBeAString")))
}
}
// So I defined the following rule (Maybe not the best way?) :
def parsePayload: Rule[(GHEvent, JsValue), GHPayload] = Rule.fromMapping {
case (pull_request, js) => Success(js.as[GHPRPayload])
case (issues, js) => Success(js.as[GHIssuePayload])
case (push, js) => Success(js.as[GHPushPayload])
case _ => Failure(Seq(ValidationError(s"error.GHEventNotImplemented")))
}
// Now I'm wondering how to compose the implicit rule of the ADTEnum and my rule (and maybe json Reads ones too) :
// String -> GHEvent => (GHEvent, JsValue) -> GHPayload
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment