Skip to content

Commit

Permalink
Add support for Short, Byte, Seq, and collection.Map
Browse files Browse the repository at this point in the history
  • Loading branch information
akara authored and BenFradet committed Sep 4, 2019
1 parent 489f2f7 commit 9687fb8
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/main/scala/pbdirect/PBReader.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ object PBReader extends PBReaderImplicits {
implicit object BooleanReader$ extends PBReader[Boolean] {
override def read(input: CodedInputStream): Boolean = input.readBool()
}
// Stored as variants, but larger in memory: https://groups.google.com/forum/#!topic/protobuf/Er39mNGnRWU
implicit object ByteReader$ extends PBReader[Byte] {
override def read(input: CodedInputStream): Byte = input.readInt32().toByte
}
// Stored as variants, but larger in memory: https://groups.google.com/forum/#!topic/protobuf/Er39mNGnRWU
implicit object ShortReader$ extends PBReader[Short] {
override def read(input: CodedInputStream): Short = input.readInt32().toShort
}
implicit object IntReader$ extends PBReader[Int] {
override def read(input: CodedInputStream): Int = input.readInt32()
}
Expand Down Expand Up @@ -180,6 +188,14 @@ trait PBParserImplicits extends LowPriorityPBParserImplicits {
instance { (index: Int, bytes: Array[Byte]) =>
parser.parse(index, bytes).toMap
}
implicit def collectionMapParser[K, V](implicit parser: PBParser[List[(K, V)]]): PBParser[collection.Map[K, V]] =
instance { (index: Int, bytes: Array[Byte]) =>
parser.parse(index, bytes).toMap
}
implicit def seqParser[A](implicit parser: PBParser[List[A]]): PBParser[Seq[A]] =
instance { (index: Int, bytes: Array[Byte]) =>
parser.parse(index, bytes)
}
}

object PBParser extends PBParserImplicits
16 changes: 16 additions & 0 deletions src/main/scala/pbdirect/PBWriter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ trait PBWriterImplicits extends LowPriorityPBWriterImplicits {
override def writeTo(index: Int, value: Boolean, out: CodedOutputStream): Unit =
out.writeBool(index, value)
}
implicit object ByteWriter extends PBWriter[Byte] {
override def writeTo(index: Int, value: Byte, out: CodedOutputStream): Unit =
out.writeInt32(index, value)
}
implicit object ShortWriter extends PBWriter[Short] {
override def writeTo(index: Int, value: Short, out: CodedOutputStream): Unit =
out.writeInt32(index, value)
}
implicit object IntWriter extends PBWriter[Int] {
override def writeTo(index: Int, value: Int, out: CodedOutputStream): Unit =
out.writeInt32(index, value)
Expand Down Expand Up @@ -120,6 +128,14 @@ trait PBWriterImplicits extends LowPriorityPBWriterImplicits {
instance { (index: Int, value: Map[K, V], out: CodedOutputStream) =>
writer.writeTo(index, value.toList, out)
}
implicit def collectionMapWriter[K, V](implicit writer: PBWriter[List[(K, V)]]): PBWriter[collection.Map[K, V]] =
instance { (index: Int, value: collection.Map[K, V], out: CodedOutputStream) =>
writer.writeTo(index, value.toList, out)
}
implicit def seqWriter[A](implicit writer: PBWriter[List[A]]): PBWriter[Seq[A]] =
instance { (index: Int, value: Seq[A], out: CodedOutputStream) =>
writer.writeTo(index, value.toList, out)
}
implicit def enumWriter[E](implicit values: Enum.Values[E], ordering: Ordering[E]): PBWriter[E] =
instance { (index: Int, value: E, out: CodedOutputStream) =>
out.writeInt32(index, Enum.toInt(value))
Expand Down
20 changes: 20 additions & 0 deletions src/test/scala/pbdirect/PBReaderSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ class PBReaderSpec extends WordSpecLike with Matchers {
val bytes = Array[Byte](8, 1)
bytes.pbTo[BooleanMessage] shouldBe BooleanMessage(Some(true))
}
"read a Byte from Protobuf" in {
case class ByteMessage(value: Option[Byte])
val bytes = Array[Byte](8, 32)
bytes.pbTo[ByteMessage] shouldBe ByteMessage(Some(32))
}
"read a Short from Protobuf" in {
case class ShortMessage(value: Option[Short])
val bytes = Array[Byte](8, -1, 63)
bytes.pbTo[ShortMessage] shouldBe ShortMessage(Some(8191))
}
"read an Int from Protobuf" in {
case class IntMessage(value: Option[Int])
val bytes = Array[Byte](8, 5)
Expand Down Expand Up @@ -105,11 +115,21 @@ class PBReaderSpec extends WordSpecLike with Matchers {
val bytes = Array[Byte](8, 1, 8, 2, 8, 3, 8, 4)
bytes.pbTo[RepeatedMessage] shouldBe RepeatedMessage(1 :: 2 :: 3 :: 4 :: Nil)
}
"read a message with Seq from Protobuf" in {
case class RepeatedMessage(values: Seq[Int])
val bytes = Array[Byte](8, 1, 8, 2, 8, 3, 8, 4)
bytes.pbTo[RepeatedMessage] shouldBe RepeatedMessage(Seq(1, 2, 3, 4))
}
"read a Map from Protobuf" in {
case class MapMessage(values: Map[Int, String])
val bytes = Array[Byte](10, 7, 8, 1, 18, 3, 111, 110, 101, 10, 7, 8, 2, 18, 3, 116, 119, 111)
bytes.pbTo[MapMessage] shouldBe MapMessage(Map(1 -> "one", 2 -> "two"))
}
"read a scala.collection.Map from Protobuf" in {
case class MapMessage(values: collection.Map[Int, String])
val bytes = Array[Byte](10, 7, 8, 1, 18, 3, 111, 110, 101, 10, 7, 8, 2, 18, 3, 116, 119, 111)
bytes.pbTo[MapMessage] shouldBe MapMessage(collection.Map(1 -> "one", 2 -> "two"))
}
"read a nested message from Protobuf" in {
case class InnerMessage(value: Option[Int])
case class OuterMessage(text: Option[String], inner: Option[InnerMessage])
Expand Down
20 changes: 20 additions & 0 deletions src/test/scala/pbdirect/PBWriterSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ class PBWriterSpec extends WordSpecLike with Matchers {
val message = BooleanMessage(Some(true))
message.toPB shouldBe Array[Byte](8, 1)
}
"write a Byte to Protobuf" in {
case class ByteMessage(value: Option[Byte])
val message = ByteMessage(Some(32))
message.toPB shouldBe Array[Byte](8, 32)
}
"write a Short to Protobuf" in {
case class ShortMessage(value: Option[Short])
val message = ShortMessage(Some(8191))
message.toPB shouldBe Array[Byte](8, -1, 63)
}
"write an Int to Protobuf" in {
case class IntMessage(value: Option[Int])
val message = IntMessage(Some(5))
Expand Down Expand Up @@ -105,12 +115,22 @@ class PBWriterSpec extends WordSpecLike with Matchers {
val message = RepeatedMessage(1 :: 2 :: 3 :: 4 :: Nil)
message.toPB shouldBe Array[Byte](8, 1, 8, 2, 8, 3, 8, 4)
}
"write a message with Seq to Protobuf" in {
case class RepeatedMessage(values: Seq[Int])
val message = RepeatedMessage(Seq(1, 2, 3, 4))
message.toPB shouldBe Array[Byte](8, 1, 8, 2, 8, 3, 8, 4)
}
"write a Map to Protobuf" in {
case class MapMessage(values: Map[Int, String])
val message = MapMessage(Map(1 -> "one", 2 -> "two"))
message.toPB shouldBe Array[Byte](10, 7, 8, 1, 18, 3, 111, 110, 101, 10, 7, 8, 2, 18, 3, 116,
119, 111)
}
"write a scala.collection.Map to Protobuf" in {
case class MapMessage(values: collection.Map[Int, String])
val message = MapMessage(collection.Map(1 -> "one", 2 -> "two"))
message.toPB shouldBe Array[Byte](10, 7, 8, 1, 18, 3, 111, 110, 101, 10, 7, 8, 2, 18, 3, 116, 119, 111)
}
"write a nested message to Protobuf" in {
case class InnerMessage(value: Option[Int])
case class OuterMessage(text: Option[String], inner: Option[InnerMessage])
Expand Down

0 comments on commit 9687fb8

Please sign in to comment.