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

orcus.bigtable.codec.DerivedFamilyDecoder.scala Maven / Gradle / Ivy

The newest version!
package orcus.bigtable.codec

import com.google.cloud.bigtable.data.v2.models.RowCell
import shapeless3.deriving.*

import scala.annotation.tailrec

trait DerivedFamilyDecoder[A] extends FamilyDecoder[A]

object DerivedFamilyDecoder extends DerivedFamilyDecoder1

private[codec] trait DerivedFamilyDecoder1:

  private val pure = [A] => (a: A) => Right(a)
  private val map  = [A, B] => (fa: Either[Throwable, A], f: A => B) => fa.map(f)
  private val tailRecM = [A, B] =>
    (a: A, f: A => Either[Throwable, Either[A, B]]) =>
      @tailrec def loop(a: A): Either[Throwable, B] = f(a) match
        case Left(err)       => Left(err)
        case Right(Left(a))  => loop(a)
        case Right(Right(b)) => Right(b)
      loop(a)

  given familyDecoderGen[A](using
    inst: K0.ProductInstances[ValueDecoder, A],
    labelling: Labelling[A]
  ): DerivedFamilyDecoder[A] with
    def apply(family: List[RowCell]): Either[Throwable, A] =
      val labels = labelling.elemLabels.iterator
      val decode = [t] =>
        (f: ValueDecoder[t]) =>
          val label = labels.next()
          val cells = family.collect { case r if r.getQualifier.toStringUtf8 == label => r }
          f(cells)
      inst.constructM(decode)(pure, map, tailRecM)

  inline def derived[A](using K0.ProductGeneric[A]): DerivedFamilyDecoder[A] = familyDecoderGen




© 2015 - 2024 Weber Informatics LLC | Privacy Policy