How do I make Codec[Option[T]] that is driven by prefix?

136 Views Asked by At

I'm trying to implement codec for PSQL COPY BINARY format. Details are at Tuple section

Int, Bool, String fields are encoded as <4 byte length><var length payload>

I implemented them like this

val psqlUtf8: Codec[String] = variableSizeBytes(int32, utf8)
val psqlBool: Codec[Boolean] = variableSizeBytes(int32, byte).xmap[Boolean](_ == 1, v ⇒ if (v) 1 else 0)
val psqlInt: Codec[Int] = variableSizeBytes(int32, int32)

But to encode NULL they use -1 in length field.

Could you please suggest how I can implement Codec[Option[T]] for such situation ?

1

There are 1 best solutions below

0
On BEST ANSWER

The best I could come up with is

def psqlNullable[T](codec: Codec[T]): Codec[Option[T]] =
  fallback(constant(-1),  codec).xmap[Option[T]]({
    case Left(_) ⇒ None
    case Right(v) ⇒ Some(v)
  }, {
    case None ⇒ Left(())
    case Some(v) ⇒ Right(v)
  })