I'm having a hard time slogging through the Argonaut documentation, so I figured I'd just ask for a simple example.
val input = """{"a":[{"b":4},{"b":5}]}"""
val output = ??? // desired value: List(4, 5)
I can get a cursor down to the array:
Parse.parse(input).map((jObjectPL >=> jsonObjectPL("a") >=> jArrayPL)(_))
// scalaz.\/[String,Option[scalaz.IndexedStore[argonaut.Argonaut.JsonArray,
// argonaut.Argonaut.JsonArray,argonaut.Json]]] =
// \/-(Some(IndexedStoreT((<function1>,List({"b":4}, {"b":5})))))
But then what? Am I on the right track? Should I even be using cursors for this?
Edit - Here's some progress, I guess. I've written a decoder for the list:
Parse.parse("""[{"b": 4}, {"b": 5}]""")
.map(_.as(IListDecodeJson(DecodeJson(_.downField("b").as[Int]))))
// scalaz.\/[String,argonaut.DecodeResult[scalaz.IList[Int]]] =
// \/-(DecodeResult(\/-([4,5])))
Edit - Slowly starting to put it together...
Parse.parse(input).map(_.as[HCursor].flatMap(_.downField("a").as(
IListDecodeJson(DecodeJson(_.downField("b").as[Int])))))
// scalaz.\/[String,argonaut.DecodeResult[scalaz.IList[Int]]] =
// \/-(DecodeResult(\/-([4,5])))
Edit - So I guess my best solution so far is:
Parse.parse(input).map(_.as(
DecodeJson(_.downField("a").as(
IListDecodeJson(DecodeJson(_.downField("b").as[Int])).map(_.toList)
))
))
Feels a bit verbose, though.
You can do this pretty nicely with the new-ish Monocle support in Argonaut (I'm using Argonaut master here, since the 6.1 milestones are still on Monocle 0.5):
import argonaut._, Argonaut._
import scalaz._, Scalaz._
import monocle._, Monocle._
val lens =
Parse.parseOptional ^<-?
jObjectPrism ^|-?
index("a") ^<-?
jArrayPrism ^|->>
each ^<-?
jObjectPrism ^|-?
index("b") ^<-?
jIntPrism
And then:
scala> lens.getAll("""{"a":[{"b":4},{"b":5}]}""")
res0: scalaz.IList[Int] = [4,5]
The operators look horrible at first, but you get used to them, and the composed pieces read pretty naturally. And of course since this is a lens there are all kinds of operations that you can use in addition to getAll
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With