uPickle serializer is a lightweight Json library for scala. uPickle is built on top of uJson which are used for easy manipulation of json without the need of converting it to a scala case class. We can even use uJson as standalone too. In this blog, I will focus only on uPickle library.
Note: uPickle does not support Scala 2.10; only 2.11 and 2.12 are supported
uPickle (pronounced micro-pickle) is a lightweight JSON serialization library which is fast than many other json serializers. I will talk more about the comparison of different serializers in my next blog. This blog will cover all the basic stuff about uPickle.
Features
- Simple to use, with nice human-readable JSON output
- Very high Performance; faster than Play-Json, Circe, or Argonaut by a large margin
- Simple & easy to understand JSON Processing API, that should be instantly familiar to anyone whose processed JSON in Python, Ruby, or Javascript
- Flexible and easily customizable
- Zero dependencies; can be included in any project without worrying about conflicts
- ScalaJS support, allowing transfer of structured data between the JVM and Javascript.
If you use uJson you will get basic operations to manipulate JSON:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package object ujson{ | |
def transform[T](t: Transformable, v: Visitor[_, T]) = t.transform(v) | |
def read(s: Transformable): Js.Value = transform(s, Js) | |
def copy(t: Js.Value): Js.Value = transform(t, Js) | |
def write(t: Js.Value, indent: Int = -1): String = { | |
transform(t, StringRenderer(indent)).toString | |
} | |
def writeTo(t: Js.Value, out: java.io.Writer, indent: Int = -1): Unit = { | |
transform(t, Renderer(out, indent)) | |
} | |
def validate(s: Transformable): Unit = transform(s, NoOpVisitor) | |
def reformat(s: Transformable, indent: Int = -1): String = { | |
transform(s, StringRenderer(indent)).toString | |
} | |
def reformatTo(s: Transformable, out: java.io.Writer, indent: Int = -1): Unit = { | |
transform(s, Renderer(out, indent)).toString | |
} | |
// End ujson | |
} |
The uPickle library that uses uJson builds on top of these, exposing similar operations that work on any type T
with a provided Reader
or Writer
:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trait Api { | |
def read[T: Reader](s: Transformable): T = s.transform(reader[T]) | |
def readJs[T: Reader](s: Js.Value): T = s.transform(reader[T]) | |
def reader[T: Reader] = implicitly[Reader[T]] | |
def write[T: Writer](t: T, indent: Int = -1): String = { | |
transform(t).to(StringRenderer(indent)).toString | |
} | |
def writeJs[T: Writer](t: T): Js.Value = transform(t).to[Js.Value] | |
def writeTo[T: Writer](t: T, out: java.io.Writer, indent: Int = -1): Unit = { | |
transform(t).to(new Renderer(out, indent = indent)) | |
} | |
def writer[T: Writer] = implicitly[Writer[T]] | |
def writable[T: Writer](t: T): Transformable = Transformable.fromTransformer(t, writer[T]) | |
def readwriter[T: ReadWriter] = implicitly[ReadWriter[T]] | |
case class transform[T: Writer](t: T) extends Transformable{ | |
def transform[V](f: ujson.Visitor[_, V]): V = writer[T].transform(t, f) | |
def to[V](f: ujson.Visitor[_, V]): V = transform(f) | |
def to[V](implicit f: Reader[V]): V = transform(f) | |
} | |
// End Api | |
} |
Now let’s see how it works.
First, we need to add the dependency in build.sbt
libraryDependencies += “com.lihaoyi” %% “upickle” % “0.6.5”
Then add this import in your code:
import upickle.default._
Scala primitive data types:
write(true: Boolean) returns true (JSON Boolean) write("Hello Upickle": String) returns "Hello Upickle" (Json String) write('A': Char) returns "A" (JSON String) write(10: Int) returns 10 (JSON Number) write(10: Float) returns 10 (JSON Number) write(10.0: Double) returns 10 (JSON Number) write(1000000L: Long) returns "10" (Json String)
Scala Collections:
write(List("Hello", "World")) returns ["Hello","World"] (JSON List) write(Array("Hello", "uPickle")) returns ["Hello","uPickle"] (JSON List)
Scala Options:
write(Some("uPickle")) returns ["uPickle"] (JSON List) write(None) returns [] (JSON List)
Scala case classes
case class MyuPickle(libraryName: String, _type: String) object MyuPickle { implicit def rw: RW[MyuPickle] = macroRW } //now to serialize it write(MyuPickle("uPickle", "JSON Serializer")) returns {"libraryName":"uPickle","_type":"JSON Serializer"} //to deserialize it read[MyuPickle]("{\"libraryName\":\"uPickle\",\"_type\":\"JSON Serializer\"}") returns MyuPickle(uPickle,JSON Serializer)
Custom read/write
import upickle.default._ case class CustomPickle(libraryName: String, _type: String) object CustomPickle { implicit val rw = upickle.default.readwriter[String].bimap[CustomPickle]( customPickle => customPickle.libraryName + " " + customPickle._type, str => { val Array(name, _type) = str.split(" ", 2) new CustomPickle(name, _type) } ) } write(CustomPickle("uPickle", "json serializer")) returns "uPickle json serializer" read[CustomPickle]("\"uPickle json serializer\"") returns CustomPickle(uPickle,json serializer)
Supported Types
uPickle provides read/write for the following types:
Boolean
,Byte
,Char
,Short
,Int
,Long
,Float
,Double
Tuple
s from 1 to 22- Immutable
Seq
,List
,Vector
,Set
,SortedSet
,Option
,Array
,Map
s, and all other collections with a reasonableCanBuildFrom
implementation Duration
,Either
- Stand-alone
case class
es andcase object
s, and their generic equivalents, - Non-generic
case class
es andcase object
s that are part of asealed trait
orsealed class
hierarchy sealed trait
andsealed class
es themselves, assuming that all subclasses are picklableUUID
snull
In my next blog, I will compare different serializers and show you how uPickle stands out from all. But let me share the stats that I have got:
Till then,
Happy reading…
Reference:
2 thoughts on “uPickle: a flexible Json Serializer3 min read”
Comments are closed.