ScalaでMessagePackのValueをパターンマッチ

MessagePack Java APIValue オブジェクトを Scala の match-case 文でパターンマッチさせたいなーと思って extractor 書いてみたらうまいこといったので貼り付けときます。

Scala 2.10.0 + msgpack 0.6.7 です。

import scala.collection.JavaConverters._
import org.msgpack.MessagePack
import org.msgpack.`type`.{ Value, NilValue => MPNilValue,
  FloatValue => MPFloatValue, IntegerValue => MPIntegerValue }

object RawValue {
  def unapply(v: Value): Option[String] =
    if (v.isRawValue) Some(v.asRawValue.getString) else None
}

object BooleanValue {
  def unapply(v: Value): Option[Boolean] =
    if (v.isBooleanValue) Some(v.asBooleanValue.getBoolean) else None
}

object IntegerValue {
  def unapply(v: Value): Option[MPIntegerValue] =
    if (v.isIntegerValue) Some(v.asIntegerValue) else None
}

object FloatValue {
  def unapply(v: Value): Option[MPFloatValue] =
    if (v.isFloatValue) Some(v.asFloatValue) else None
}

object NilValue {
  def unapply(v: Value): Option[MPNilValue] =
    if (v.isNilValue) Some(v.asNilValue) else None
}

object ArrayValue {
  def unapply(v: Value): Option[Seq[Value]] =
    if (v.isArrayValue) Some(v.asArrayValue.asScala) else None
}

object MapValue {
  def unapply(v: Value): Option[collection.mutable.Map[Value, Value]] =
    if (v.isMapValue) Some(v.asMapValue.asScala) else None
}
val msgpack = new MessagePack
val packer = msgpack.createBufferPacker
packer.write("hello")
packer.write(123)
packer.write(Array("foo", "bar", "baz"))
packer.write(-56.789f)
packer.write(true)
packer.write(Map("dog" -> "inu", "cat" -> "neko").asJava)
packer.writeNil
val bytes = packer.toByteArray

val unpacker = msgpack.createBufferUnpacker(bytes)
unpacker.asScala.foreach {
  case ArrayValue(a) => println("[array] "+ a.mkString(", "))
  case MapValue(m) => println("[map] "+ m)
  case RawValue(s) => println("[raw] "+ s)
  case IntegerValue(n) => println("[int] "+ n)
  case FloatValue(n) => println("[float] "+ n)
  case BooleanValue(b) => println("[bool] "+ b)
  case NilValue(n) => println("[nil]")
  case x => println("[???] "+ x)
}

asJava とか asScala が気持ち悪い人は「import scala.collection.JavaConversions._」すれば消せます。