All Downloads are FREE. Search and download functionalities are using the official Maven repository.

redis.Converter.scala Maven / Gradle / Ivy

The newest version!
package redis

import akka.util.ByteString
import redis.protocol._
import scala.util.Try
import scala.annotation.{tailrec, implicitNotFound}
import scala.collection.mutable

trait MultiBulkConverter[A] {
  def to(redisReply: MultiBulk): Try[A]
}

object MultiBulkConverter {

  def toSeqString(reply: MultiBulk): Seq[String] = {
    reply.responses.map(r => {
      r.map(_.toString)
    }).getOrElse(Seq.empty)
  }

  def toSeqByteString[R](reply: MultiBulk)(implicit deserializer: ByteStringDeserializer[R]): Seq[R] = {
    reply.responses.map(r => {
      r.map(reply => deserializer.deserialize(reply.toByteString))
    }).getOrElse(Seq.empty)
  }

  def toSeqOptionByteString[R](reply: MultiBulk)(implicit deserializer: ByteStringDeserializer[R]): Seq[Option[R]] = {
    reply.responses.map(r => {
      r.map(_.asOptByteString.map(deserializer.deserialize))
    }).getOrElse(Seq.empty)
  }

  def toSeqTuple2ByteStringDouble[R](reply: MultiBulk)(implicit deserializer: ByteStringDeserializer[R]): Seq[(R, Double)] = {
    reply.responses.map {
      r => {
        val s = r.map(_.toByteString)
        val builder = Seq.newBuilder[(R, Double)]
        s.grouped(2).foreach {
          case Seq(a, b) => builder += ((deserializer.deserialize(a), b.utf8String.toDouble))
        }
        builder.result()
      }
    }.getOrElse(Seq.empty)
  }


  def toClusterSlots(reply: MultiBulk) = {
    reply.responses.map{
      slot => {
        val elementSeq = slot.toSeq
        val begin = elementSeq(0).toByteString
        val end = elementSeq(1).toByteString
        (begin,end)
      }
    }
  }



  def toMapString(reply: MultiBulk): Map[String, String] = {
    reply.responses.map(bs => {
      val builder = Map.newBuilder[String, String]
      seqtoMapString(bs, builder)
      builder.result()
    }).getOrElse(Map.empty)
  }

  @tailrec
  private def seqtoMapString(bsSeq: Seq[RedisReply], acc: mutable.Builder[(String, String), Map[String, String]]): Unit = {
    if (bsSeq.nonEmpty) {
      acc += ((bsSeq.head.asOptByteString.map(_.utf8String).getOrElse(""), bsSeq.tail.head.asOptByteString.map(_.utf8String).getOrElse("")))
      seqtoMapString(bsSeq.tail.tail, acc)
    }
  }

  def toSeqMapString(reply: MultiBulk): Seq[Map[String, String]] = {
    reply.responses.map {
      s =>
        s.map({
          case m: MultiBulk =>
            m.responses.map {
              s =>
                val builder = Seq.newBuilder[(String, String)]
                s.grouped(2).foreach {
                  case Seq(a, b) => builder += ((a.toString, b.toString))
                }
                builder.result()
            }.getOrElse(Seq())

          case _ => Seq()
        }).map {
          _.toMap
        }
    }.getOrElse(Seq.empty)
  }

  def toOptionStringByteString[R](reply: MultiBulk)(implicit deserializer: ByteStringDeserializer[R]): Option[(String, R)] = {
    reply.responses.map(r => {
      Some(r.head.toString -> deserializer.deserialize(r.tail.head.toByteString))
    }).getOrElse(None)
  }

  def toSeqBoolean(reply: MultiBulk): Seq[Boolean] = {
    reply.responses.map(r => {
      r.map(_.toString == "1")
    }).getOrElse(Seq.empty)
  }

  def toStringsSeq(rd : RedisReply ): Seq[String] = rd match {
    case MultiBulk(Some(v)) => v.flatMap(r => toStringsSeq(r))
    case Bulk(b) => b.map(_.decodeString("US-ASCII")).toSeq
    case Integer(i) => Seq(i.decodeString("US-ASCII"))
    case _ => Nil
  }

}

@implicitNotFound(msg = "No ByteString serializer found for type ${K}. Try to implement an implicit ByteStringSerializer for this type.")
trait ByteStringSerializer[K] { self =>
  def serialize(data: K): ByteString

  def contramap[A](f: A => K): ByteStringSerializer[A] =
    new ByteStringSerializer[A] {
      def serialize(data: A) = self.serialize(f(data))
    }
}

object ByteStringSerializer extends ByteStringSerializerLowPriority

trait ByteStringSerializerLowPriority {

  implicit object String extends ByteStringSerializer[String] {
    def serialize(key: String): ByteString = ByteString(key)
  }

  implicit object ShortConverter extends ByteStringSerializer[Short] {
    def serialize(i: Short): ByteString = ByteString(i.toString)
  }

  implicit object IntConverter extends ByteStringSerializer[Int] {
    def serialize(i: Int): ByteString = ByteString(i.toString)
  }

  implicit object LongConverter extends ByteStringSerializer[Long] {
    def serialize(i: Long): ByteString = ByteString(i.toString)
  }

  implicit object FloatConverter extends ByteStringSerializer[Float] {
    def serialize(f: Float): ByteString = ByteString(f.toString)
  }

  implicit object DoubleConverter extends ByteStringSerializer[Double] {
    def serialize(d: Double): ByteString = ByteString(d.toString)
  }

  implicit object CharConverter extends ByteStringSerializer[Char] {
    def serialize(c: Char): ByteString = ByteString(c)
  }

  implicit object ByteConverter extends ByteStringSerializer[Byte] {
    def serialize(b: Byte): ByteString = ByteString(b)
  }

  implicit object ArrayByteConverter extends ByteStringSerializer[Array[Byte]] {
    def serialize(b: Array[Byte]): ByteString = ByteString(b)
  }

  implicit object ByteStringConverter extends ByteStringSerializer[ByteString] {
    def serialize(bs: ByteString): ByteString = bs
  }

}

@implicitNotFound(msg = "No ByteString deserializer found for type ${T}. Try to implement an implicit ByteStringDeserializer for this type.")
trait ByteStringDeserializer[T] { self =>
  def deserialize(bs: ByteString): T

  def map[A](f: T => A): ByteStringDeserializer[A] =
    new ByteStringDeserializer[A] {
      def deserialize(bs: ByteString) = f(self.deserialize(bs))
    }
}

object ByteStringDeserializer extends ByteStringDeserializerLowPriority

trait ByteStringDeserializerLowPriority extends ByteStringDeserializerDefault {

  implicit object ByteString extends ByteStringDeserializer[ByteString] {
    def deserialize(bs: ByteString): ByteString = bs
  }

}

trait ByteStringDeserializerDefault {

  implicit object String extends ByteStringDeserializer[String] {
    def deserialize(bs: ByteString): String = bs.utf8String
  }

  implicit object ByteArray extends ByteStringDeserializer[Array[Byte]] {
    def deserialize(bs: ByteString): Array[Byte] = bs.toArray
  }

  implicit object RedisDouble extends ByteStringDeserializer[Double] {
    override def deserialize(bs: ByteString): Double = {
      val s = bs.utf8String
      if ("-inf".equals(s))
        Double.NegativeInfinity
      else if ("inf".equals(s))
        Double.PositiveInfinity
      else
        java.lang.Double.parseDouble(s)
    }
  }

}

trait ByteStringFormatter[T] extends ByteStringSerializer[T] with ByteStringDeserializer[T]



@implicitNotFound(msg = "No RedisReplyDeserializer deserializer found for type ${T}. Try to implement an implicit RedisReplyDeserializer for this type.")
trait RedisReplyDeserializer[T] {
  def deserialize: PartialFunction[RedisReply, T]
}

object RedisReplyDeserializer extends RedisReplyDeserializerLowPriority

trait RedisReplyDeserializerLowPriority extends RedisReplyDeserializerDefault {

  implicit object RedisReply extends RedisReplyDeserializer[RedisReply] {
    def deserialize: PartialFunction[RedisReply, RedisReply] = {
      case reply => reply
    }
  }

}

trait RedisReplyDeserializerDefault {

  implicit object String extends RedisReplyDeserializer[String] {
    def deserialize : PartialFunction[RedisReply, String] = {
      case Bulk(Some(bs)) => bs.utf8String
    }
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy