Skip to content

Instantly share code, notes, and snippets.

@stonegao
Forked from heathermiller/EdnPickleFormat.scala
Created June 17, 2013 11:05
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 stonegao/5796163 to your computer and use it in GitHub Desktop.
Save stonegao/5796163 to your computer and use it in GitHub Desktop.
import scala.pickling._
import scala.reflect.runtime.universe._
import scala.util.parsing.json._
import scala.collection.mutable.{StringBuilder, Stack}
package object edn {
implicit val pickleFormat: EdnPickleFormat = new EdnPickleFormat
}
package edn {
case class EdnPickle(value: String) extends Pickle {
type ValueType = String
type PickleFormatType = EdnPickleFormat
}
class EdnPickleFormat extends PickleFormat {
type PickleType = EdnPickle
def createBuilder() = new EdnPickleBuilder(this)
def createReader(pickle: EdnPickle, mirror: Mirror) = ???
}
class EdnPickleBuilder(format: EdnPickleFormat) extends PBuilder with PickleTools {
private val buf = new StringBuilder()
private val tags = new Stack[FastTypeTag[_]]()
private def append(s: String) = buf ++= s
private def pickleArray(arr: Array[_], tag: FastTypeTag[_]) = {
append("[")
hintStaticallyElidedType()
hintTag(tag)
pinHints()
var i = 0
while (i < arr.length) {
putElement(b => b.beginEntry(arr(i)).endEntry())
i += 1
}
unpinHints()
append("]")
}
private val primitives = Map[String, Any => Unit](
FastTypeTag.Null.key -> ((picklee: Any) => append("null")),
FastTypeTag.Int.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Long.key -> ((picklee: Any) => append("\"" + JSONFormat.quoteString(picklee.toString) + "\"")),
FastTypeTag.Short.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Double.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Float.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Boolean.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Byte.key -> ((picklee: Any) => append(picklee.toString)),
FastTypeTag.Char.key -> ((picklee: Any) => append("\"" + JSONFormat.quoteString(picklee.toString) + "\"")),
FastTypeTag.ScalaString.key -> ((picklee: Any) => append("\"" + JSONFormat.quoteString(picklee.toString) + "\"")),
FastTypeTag.JavaString.key -> ((picklee: Any) => append("\"" + JSONFormat.quoteString(picklee.toString) + "\"")),
FastTypeTag.ArrayInt.key -> ((picklee: Any) => pickleArray(picklee.asInstanceOf[Array[Int]], FastTypeTag.Int))
)
def beginEntry(picklee: Any): this.type = withHints { hints =>
tags.push(hints.tag)
if (primitives.contains(hints.tag.key)) {
if (hints.isElidedType) primitives(hints.tag.key)(picklee)
else ???
} else append("#pickling/" + typeToString(hints.tag.tpe) + " {")
this
}
def putField(name: String, pickler: this.type => Unit): this.type = {
append(" :" + name + " ")
pickler(this)
this
}
def endEntry(): Unit = {
if (primitives.contains(tags.pop().key)) {} // do nothing
else append(" }")
}
def beginCollection(length: Int): this.type = {
putField("elems", b => ())
append("[")
this
}
def putElement(pickler: this.type => Unit): this.type = {
if (buf.toString.trim.last != '[') append(", ")
pickler(this)
this
}
def endCollection(l: Int): Unit = append("]")
def result(): EdnPickle = EdnPickle(buf.toString)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment