Skip to content

Instantly share code, notes, and snippets.

@vsuharnikov
Created September 14, 2017 11:08
Show Gist options
  • Save vsuharnikov/4eb443217d150498c646932032a9c22a to your computer and use it in GitHub Desktop.
Save vsuharnikov/4eb443217d150498c646932032a9c22a to your computer and use it in GitHub Desktop.
Serialization and deserialization example
import com.google.common.primitives.Ints
import scala.collection.breakOut
trait Serializable[From, To] {
def serialize(x: From): To
}
trait Deserializable[From, To] {
def deserialize(x: From): To
}
trait BytesSerializable[Value] extends Serializable[Value, Array[Byte]] with Deserializable[Iterator[Byte], Value]
implicit val intToBytes: BytesSerializable[Int] = new BytesSerializable[Int] {
override def serialize(x: Int): Array[Byte] = Ints.toByteArray(x)
override def deserialize(bytes: Iterator[Byte]): Int = {
// take doesn't modify the state of bytes, LOL
val b: Array[Byte] = (1 to Ints.BYTES).map(_ => bytes.next())(breakOut)
Ints.fromByteArray(b)
}
}
implicit def seqToBytes[ElementT: BytesSerializable]
: BytesSerializable[Seq[ElementT]] = new BytesSerializable[Seq[ElementT]] {
private val sizeSer = implicitly[BytesSerializable[Int]]
private val elemSer = implicitly[BytesSerializable[ElementT]]
override def serialize(xs: Seq[ElementT]): Array[Byte] = {
xs.foldLeft(sizeSer.serialize(xs.size)) { case (r, c) => r ++ elemSer.serialize(c) }
}
override def deserialize(x: Iterator[Byte]): Seq[ElementT] = {
val size = sizeSer.deserialize(x)
(1 to size).foldLeft(Seq.empty[ElementT]) { case (r, _) =>
val c = elemSer.deserialize(x)
r :+ c
}
}
}
val s = implicitly[BytesSerializable[Seq[Int]]]
val origXs = Seq(1, 2, 3)
val bytes = s.serialize(origXs)
val actXs = s.deserialize(bytes.toIterator)
actXs == origXs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment