argonaut
argonaut copied to clipboard
Add filter/withFilter to DecodeResult
Per the discussion #133, a filter
/withFilter
method is useful to allow the use of pattern guards when applying post processing logic to DecodeResult
instances. A simple example of when this is useful is in dealing with algebraic data types with case object instances. Such an instance might be encoded as a string in json, but when decoding json, the proper object must be selected based on the string value. Consider the following type State
:
sealed trait State(name: String)
case object Open extends State("open")
case object Closed extends State("closed")
object State {
val all = Set(Open, Closed)
def unapply(s: String) =
all.find(_.name == s)
}
If Open
is encoded as {"name": "open"}
, then we could use the State
extractor via a pattern guard (and therefore filter
/withFilter
):
DecodeJson(c => for {
State(s) <- (c --\ "name").as[String]
} yield s)
It became clear in chatting with @markhibberd that the best possible implementation of filter
would provide a generic explanation while preserving the history. Therefore it should be in terms of #135 and thus requires #134.
I'm not hugely bound to making a filter method that honours the needs of for comprehensions in Scala if requiring a message like the DecodeJson.validate better suits our needs.