我目前正在實現一個庫來對XML-RPC消息進行序列化和反序列化。這幾乎完成,但現在我試圖刪除我當前的樣板使用方法無形。我當前的代碼:如何使用屬性和類型類構造不成形的case類?
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}
}
我的目標是讓我的媒體庫的用戶序列化/反序列化的情況下類,而不必強迫他寫的樣板代碼。目前,您必須使用前面提到的asProduct方法來聲明案例類和一個隱式的val,以便在上下文中具有一個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)
這是序列化和使用類型類解串的經典的策略。
在這一刻,我已經掌握瞭如何從案例類HList通過通用或LabelledGeneric轉換。問題是一旦我完成了這個轉換,我可以像在asProduct2的例子中一樣,調用方法fromXmlrpc和toXmlrpc。我沒有關於案例類中屬性類型的任何信息,因此,編譯器找不到任何隱含的,從Xmlrpc和到Xmlrpc滿足。我需要一種方法來限制一個HList的所有元素在上下文中都有一個隱含的數據類型。
由於我是一名無形的初學者,我想知道獲得此功能的最佳方式是什麼。我有一些見解,但我絕對不知道如何使用無形來完成它。理想情況是有辦法從案例類的給定屬性獲取類型,並將其明確地從0xmlrpc和轉換爲,並將其類型傳遞給0xmlrpc。我想這不是如何做到的。