2

uPickle: a flexible Json Serializer

 3 years ago
source link: https://blog.knoldus.com/upickle-a-flexible-json-serializer/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

uPickle: a flexible Json Serializer

Reading Time: 2 minutes

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-JsonCirce, 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:

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:

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:

  • BooleanByteCharShortIntLongFloatDouble
  • Tuples from 1 to 22
  • Immutable SeqListVectorSetSortedSetOptionArrayMaps, and all other collections with a reasonable CanBuildFrom implementation
  • DurationEither
  • Stand-alone case classes and case objects, and their generic equivalents,
  • Non-generic case classes and case objects that are part of a sealed trait or sealed classhierarchy
  • sealed trait and sealed classes themselves, assuming that all subclasses are picklable
  • UUIDs
  • null

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:

uPickle

Till then,

Happy reading…

Reference:

uPickle Documentation



About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK