2017-02-03 4 views
1

мои классы выглядят как этотформат JSON для дженериков в Play 2.x

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, который возвращает Reads для Option (общего типа), вы должны сначала обеспечить соблюдение, что параметр типа Value является сам предоставил необходимые экземпляры Reads и Writes.

Таким образом, для общего 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

Благодарим вас, кажется, более или менее понятным (по крайней мере, стоит взглянуть на вариант варианта). Как вы думаете, что делать с классом case Foo (атрибуты: Map [Attribute, Value [_]])? –

+0

Вы не можете, так как '_' означает, что параметр типа неизвестен. Вам понадобится 'Foo [T]' – cchantep

+0

, но я хочу, чтобы эта Карта [Атрибут, Значение [_]] содержала оба типа StringValue и NumberValue –

Смежные вопросы