将[String,Array[Byte]]映射到Scala无形状的CaseClass

将[String,Array[Byte]]映射到Scala无形状的CaseClass,scala,shapeless,Scala,Shapeless,因此,我有一个有效的实现,除了在使用LabelledGenerics构建CaseClass对象之前,我无法以正确的顺序获取HList之外 现在起作用的是 case class Foo(a:int, b:String) val serializedRecord("a" -> somebytes, "b" -> someotherbytes) val caseClassObject = HBaseSerDe[Foo].deserialize(serializedRecord) 不起作用

因此,我有一个有效的实现,除了在使用LabelledGenerics构建CaseClass对象之前,我无法以正确的顺序获取HList之外

现在起作用的是

case class Foo(a:int, b:String)
val serializedRecord("a" -> somebytes, "b" -> someotherbytes)
val caseClassObject = HBaseSerDe[Foo].deserialize(serializedRecord)
不起作用的是:

case class Foo(a:int, b:String)
val serializedRecord(x -> value1 ,"a" -> somebytes, "b" -> someotherbytes, z -> value2)
//expected Foo(somebytes, someotherbytes)
val caseClassObject = HBaseSerDe[Foo].deserialize(serializedRecord)
从我所读到的内容来看,在反序列化之前,我应该使用Align和Intersect来整理我的Hlist,但在所有示例中,我都可以发现它们使用了如下内容(摘自github.com/下划线io/shapeless guide)

隐式定义泛型迁移[
A、 B,,

ARepr我现在已经解决了这个问题,这是给后代的解决方案。事后看来,这很简单

import shapeless.labelled.FieldType
import shapeless.{::, Generic, HList, HNil, LabelledGeneric, Witness}
import shapeless.labelled.{FieldType, _}


object MapToCaseClass {


  sealed trait RecordConverter[V, TargetType] {
    def convert(rawRecord: Map[String,V]):TargetType
  }


  implicit def hNilConverter[V]:RecordConverter[V, HNil] = instance[V,HNil](
    _ => HNil
  )

  implicit def hListConverter[V, H, T <: HList, K <: Symbol](implicit fieldConverter: FieldConverter[V, H], tailConverter:RecordConverter[V, T], key: Witness.Aux[K]):RecordConverter[V, FieldType[K, H] :: T] =
    instance[V, FieldType[K, H] :: T](
      fieldMap => {
        val currentKeyName = key.value.name
        val value = fieldMap(currentKeyName)
        val mapRest = fieldMap.filterKeys(_!=currentKeyName)
        //TODO: Add a way for default value providing, Option handling and nested HLists for in case no value was found
        field[K](fieldConverter.convert(value)) :: tailConverter.convert(mapRest)
      }
    )

  implicit def caseClassConverter[V, C, CRepr <: HList](implicit caseClassGenRepr: LabelledGeneric.Aux[C,CRepr], recordConverter:RecordConverter[V, CRepr]):RecordConverter[V, C] =
    instance[V, C](
      fieldMap => {
        caseClassGenRepr.from(recordConverter.convert(fieldMap))
      }
    )

  private[this] def instance[V, T](func: Map[String,V] => T) : RecordConverter[V, T] = new RecordConverter[V, T] {
    override def convert(rawRecord: Map[String, V]): T = func(rawRecord)
  }

  //summoner
  def apply[V, T](implicit recordConverter: RecordConverter[V, T]):RecordConverter[V, T] = recordConverter


}
导入shapeless.labeled.FieldType
导入无形状。{::,通用,HList,HNil,LabelledGeneric,Witness}
导入无形状。带标签。{FieldType,}
对象映射类{
密封式转换器[V,TargetType]{
def convert(rawRecord:Map[String,V]):TargetType
}
隐式def hNilConverter[V]:RecordConverter[V,HNil]=实例[V,HNil](
_=>HNil
)
隐式def hListConverter[V,H,T]:RecordConverter[V,T]=新的RecordConverter[V,T]{
重写def convert(rawRecord:Map[String,V]):T=func(rawRecord)
}
//召唤者
def apply[V,T](隐式记录转换器:记录转换器[V,T]):记录转换器[V,T]=记录转换器
}
 implicit val hNilEncoder = instance[HNil](
    r => Map(),
    l => HNil
  )

  implicit def hListSerDe[
      Key <: Symbol, 
      H, 
      T <: HList
    ](
     implicit
     key: Witness.Aux[Key],
     headSerDe: HBaseFieldShapelessSerDe[H],
     tailSerDe: HBaseRecordShapelessSerDe[T]
     ): HBaseRecordShapelessSerDe[FieldType[Key, H] :: T] = 
    instance[FieldType[Key, H] :: T](
      hList => {
        Map(key.value.name -> headSerDe.serialize(hList.head)) ++ tailSerDe.serialize(hList.tail)
      },
      byteList => {
        field[Key](headSerDe.deSerialize(byteList.head._2)) :: tailSerDe.deSerialize(byteList.tail)
      }
    )

  implicit def caseClassSerDe[
      TargetType, 
      L <: HList
  ](
    implicit 
    genRepr: LabelledGeneric.Aux[TargetType, L], 
    hListSerDe: HBaseRecordShapelessSerDe[L]
    ): HBaseRecordShapelessSerDe[TargetType] = 
    instance[TargetType](
      hList => {
        hListSerDe.serialize(genRepr.to(hList))
      },
      byteList => {

        genRepr.from(hListSerDe.deSerialize(byteList))
      }
    )


  def apply[RecordSerDeType](implicit serde: HBaseRecordShapelessSerDe[RecordSerDeType]): HBaseRecordShapelessSerDe[RecordSerDeType] = serde

  def instance[RecordSerDeType](serializeFunc: RecordSerDeType => Map[String, Array[Byte]], deserializeFunc: Map[String, Array[Byte]] => RecordSerDeType): HBaseRecordShapelessSerDe[RecordSerDeType] = {
    new HBaseRecordShapelessSerDe[RecordSerDeType] {
      override def serialize(value: RecordSerDeType): Map[String, Array[Byte]] = serializeFunc(value)

      override def deSerialize(value: Map[String, Array[Byte]]): RecordSerDeType = deserializeFunc(value)
    }
  }
import shapeless.labelled.FieldType
import shapeless.{::, Generic, HList, HNil, LabelledGeneric, Witness}
import shapeless.labelled.{FieldType, _}


object MapToCaseClass {


  sealed trait RecordConverter[V, TargetType] {
    def convert(rawRecord: Map[String,V]):TargetType
  }


  implicit def hNilConverter[V]:RecordConverter[V, HNil] = instance[V,HNil](
    _ => HNil
  )

  implicit def hListConverter[V, H, T <: HList, K <: Symbol](implicit fieldConverter: FieldConverter[V, H], tailConverter:RecordConverter[V, T], key: Witness.Aux[K]):RecordConverter[V, FieldType[K, H] :: T] =
    instance[V, FieldType[K, H] :: T](
      fieldMap => {
        val currentKeyName = key.value.name
        val value = fieldMap(currentKeyName)
        val mapRest = fieldMap.filterKeys(_!=currentKeyName)
        //TODO: Add a way for default value providing, Option handling and nested HLists for in case no value was found
        field[K](fieldConverter.convert(value)) :: tailConverter.convert(mapRest)
      }
    )

  implicit def caseClassConverter[V, C, CRepr <: HList](implicit caseClassGenRepr: LabelledGeneric.Aux[C,CRepr], recordConverter:RecordConverter[V, CRepr]):RecordConverter[V, C] =
    instance[V, C](
      fieldMap => {
        caseClassGenRepr.from(recordConverter.convert(fieldMap))
      }
    )

  private[this] def instance[V, T](func: Map[String,V] => T) : RecordConverter[V, T] = new RecordConverter[V, T] {
    override def convert(rawRecord: Map[String, V]): T = func(rawRecord)
  }

  //summoner
  def apply[V, T](implicit recordConverter: RecordConverter[V, T]):RecordConverter[V, T] = recordConverter


}