2017-02-03 60 views
1

我的課是這樣JSON格式

trait Value[T] { 
    def get:T 
} 

我有這樣的實現,例如

class StringValue(value : String) extends Value[String] { 
    override def get : String = value 
} 

class NumberValue(value : Int) extends Value[Int] { 
    override def get: Int = value 
} 

的問題是,我需要jsonFormat此類型爲了將其保存到MongoDB。

我stucked兩天,但仍然無法弄清楚如何使它工作

回答

2

至於提供.nullable返回ReadsOption(通用型),您需要先強制執行的Value類型參數本身提供了ReadsWrites的必需實例。

因此,對於通用的Reads[Value[T]],最小的def將如下所示。

def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] = ??? 

相若方式,對於Writes[Value[T]](或OWrites如果它需要被限制到JSON對象,並且因此BSON文件),最小的定義將是如下。

def valueWrites[T](implicit underlying: Writes[T]): Writes[Value[T]] = ??? 
// or 
def valueOWrites[T](implicit underlying: Writes[T]): OWrites[Value[T]] = ??? // don't define both as implicit to avoid conflict 

則實現取決於你想表示Value[T]作爲JSON的方式。

考慮以下JSON表示:

{ "_value": ... } 

...那麼Reads會是這樣的波紋管。

implicit def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] = 
    Reads[Value[T]] { json => 
    (json \ "_value").validate(underlying).map { t: T => 
     Value(t) 
    } 
    } 

相似的,OWrites[Value[T]]如下。

implicit def valueWrites[T](implicit underlying: Writes[T]): OWrites[Value[T]] = 
    OWrites[Value[T]] { value => Json.obj("_value" -> value) } 

顯然,這些implicits需要在隱式範圍,無論是通過在Value同伴對象被限定,或者通過如在其他地方定義明確地導入。

+0

謝謝,這似乎或多或少清楚(至少看看選擇示例是個好主意)。你如何看待如何處理案例類Foo(屬性:Map [A​​ttribute,Value [_]])呢? –

+0

你不能,因爲'_'表示類型參數是未知的。你需要一個'Foo [T]' – cchantep

+0

但我希望這個Map [A​​ttribute,Value [_]]既包含StringValue也包含NumberValue –