В настоящее время я реализую библиотеку для сериализации и десериализации сообщений XML-RPC и из них. Это почти сделано, но теперь я пытаюсь удалить шаблон моего текущего метода asProduct, используя Shapeless. Мой текущий код:
trait Serializer[T] {
def serialize(value: T): NodeSeq
}
trait Deserializer[T] {
type Deserialized[T] = Validation[AnyErrors, T]
type AnyErrors = NonEmptyList[AnyError]
def deserialize(from: NodeSeq): Deserialized[T]
}
trait Datatype[T] extends Serializer[T] with Deserializer[T]
// Example of asProduct, there are 20 more methods like this, from arity 1 to 22
def asProduct2[S, T1: Datatype, T2: Datatype](apply: (T1, T2) => S)(unapply: S => Product2[T1, T2]) = new Datatype[S] {
override def serialize(value: S): NodeSeq = {
val params = unapply(value)
val b = toXmlrpc(params._1) ++ toXmlrpc(params._2)
b.theSeq
}
// Using scalaz
override def deserialize(from: NodeSeq): Deserialized[S] = (
fromXmlrpc[T1](from(0)) |@| fromXmlrpc[T2](from(1))
) {apply}
}
Моя цель - разрешить пользователю моей библиотеки сериализовать/десериализовать классы case, не заставляя его писать шаблонный код. В настоящее время вы должны объявить класс case и неявный val, используя вышеупомянутый метод asProduct, чтобы иметь экземпляр Datatype в контексте. Этот неявный используется в следующем коде:
def toXmlrpc[T](datatype: T)(implicit serializer: Serializer[T]): NodeSeq =
serializer.serialize(datatype)
def fromXmlrpc[T](value: NodeSeq)(implicit deserializer: Deserializer[T]): Deserialized[T] =
deserializer.deserialize(value)
Это классическая стратегия сериализации и десериализации с использованием классов типов.
В этот момент я понял, как преобразовать из классов case в HList через Generic или LabelledGeneric. Проблема заключается в том, что когда я это преобразование сделал, как я могу вызвать методы fromXmlrpc и toXmlrpc, как в примере asProduct2. У меня нет никакой информации о типах атрибутов в классе case, и поэтому компилятор не может найти никаких неявных, которые удовлетворяют fromXmlrpc и toXmlrpc. Мне нужен способ ограничить, что все элементы HList имеют неявный тип данных в контексте.
Как я начинаю с Shapeless, я хотел бы знать, какой лучший способ получить эту функциональность. У меня есть некоторые идеи, но я определенно понятия не имею, как это сделать, используя Shapeless. Идеальным было бы получить способ получить тип от данного атрибута класса case и передать этот тип явно изXmlrpc и toXmlrpc. Я полагаю, что это не так, как это можно сделать.