Skip to content

Instantly share code, notes, and snippets.

@d6y
Created September 1, 2014 16:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save d6y/612f803268d993d9b4bd to your computer and use it in GitHub Desktop.
Save d6y/612f803268d993d9b4bd to your computer and use it in GitHub Desktop.
SYB from Json
import shapeless._, poly._
object SYBMain extends App {
// Play JSON boils down to:
sealed trait JsValue
case object JsNull extends JsValue
case class JsObject (fields: Seq[(String, JsValue)]) extends JsValue
case class JsNumber (value : BigDecimal) extends JsValue
case class JsArray (value : Seq[JsValue] = List()) extends JsValue
case class JsString (value : String) extends JsValue
case class JsBoolean (value : Boolean) extends JsValue
// This tree contains JsNull values. They must go.
val tree : JsValue =
JsObject(Seq(
("cat" -> JsNumber(4)),
("dog" -> JsNumber(4)),
("car" -> JsNull),
("nested" ->
JsObject(Seq(
"train" -> JsNull,
"squirrel" -> JsNumber(4)
)) ),
("array" -> JsArray(Seq(JsString("rabbit"), JsNull, JsString("bird"))))
))
// SYB currently does Lists out of the box. This gives us Seq:
object ShapelessDataSeqOps {
implicit def seqDataT[F <: Poly, T, U](implicit ft : Case1.Aux[F, T, U]): DataT[F, Seq[T], Seq[U]] =
new DataT[F, Seq[T], Seq[U]] {
def gmapT(t : Seq[T]) = t.map(ft)
}
}
import ShapelessDataSeqOps._
object fix extends Poly1 {
implicit def removeFromObj = at[Seq[(String,JsValue)]](
seq => seq.filter{ case (k, JsNull) => false ; case _ => true }
)
implicit def removeFromArray = at[Seq[JsValue]](seq => seq.filter{ case JsNull => false; case _ => true })
}
println(
everywhere(fix)(tree)
)
// Result:
// JsObject(List((cat,JsNumber(4)), (dog,JsNumber(4)), (nested,JsObject(List((squirrel,JsNumber(4))))), (array,JsArray(List(JsString(rabbit), JsString(bird))))))
}
@d6y
Copy link
Author

d6y commented Sep 4, 2014

Or:

  object fix extends Poly1 {
    implicit def removeFromObj   = at[Seq[(String,JsValue)]](_.filter(withoutNull))
    implicit def removeFromArray = at[Seq[JsValue]](_.filter(withoutNull))

    private def withoutNull[T](node: T): Boolean = node match {
      case (_, JsNull) => false
      case JsNull      => false
      case _           => true
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment