Reputation: 316
my classes look like this
trait Value[T] {
def get:T
}
I have implementations of this, for example
class StringValue(value : String) extends Value[String] {
override def get : String = value
}
class NumberValue(value : Int) extends Value[Int] {
override def get: Int = value
}
The problem is that I need to make jsonFormat for this types in order to save it to MongoDB.
I stucked for two days but still cannot figure out how to make it work
Upvotes: 1
Views: 2283
Reputation: 9168
As for the provided .nullable
which returns Reads
for Option
(generic type), you need to first enforce that the type parameter of Value
is itself provided the required instances of Reads
and Writes
.
So for a generic Reads[Value[T]]
the minimal def
would be as bellow.
def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] = ???
Similarily, for Writes[Value[T]]
(or OWrites
if it needs to be restricted to JSON object, and thus BSON document), the minimal definition would be as following.
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
Then the implementation depends on the way you want to represent Value[T]
as JSON.
Considering the following JSON representation:
{ "_value": ... }
... then the Reads
would be something as bellow.
implicit def valueReads[T](implicit underlying: Reads[T]): Reads[Value[T]] =
Reads[Value[T]] { json =>
(json \ "_value").validate(underlying).map { t: T =>
Value(t)
}
}
Similarily, the OWrites[Value[T]]
would be as following.
implicit def valueWrites[T](implicit underlying: Writes[T]): OWrites[Value[T]] =
OWrites[Value[T]] { value => Json.obj("_value" -> value) }
Obviously, these implicits need to be in the implicit scope, either by being defined in the
Value
companion object, or by being explicitly imported if defined elsewhere.
Upvotes: 4