How can I create a play.api.libs.Reads
for my People
case class?
scala> type Id = Long
defined type alias Id
scala> case class People(names: Set[Id])
defined class People
scala> implicit val PeopleReads: Reads[People] = (
| (__ \ "names").read[Set[Id]])(People)
<console>:21: error: overloaded method value read with alternatives:
(t: Set[Id])play.api.libs.json.Reads[Set[Id]] <and>
(implicit r: play.api.libs.json.Reads[Set[Id]])play.api.libs.json.Reads[Set[Id]]
cannot be applied to (People.type)
(__ \ "names").read[Set[Id]])(People)
The (...)(People)
syntax is designed for when you've built up a list of arguments (well, technically it's a Builder
, not a list) with and
and want to lift the People
constructor into the applicative functor for Reads
so that you can apply it to those arguments.
For example, if your People
type looked like this:
case class People(names: Set[Id], home: String)
You could write:
implicit val PeopleReads: Reads[People] = (
(__ \ "names").read[Set[Id]] and
(__ \ "home").read[String]
)(People)
In your case, though, the constructor for People
has a single argument, and you haven't used and
, so you don't have a Builder[Reads[Set[Id] ~ String]
, you've just got a plain old Reads[Set[Id]]
.
This is nice, because it means you don't need the weird applicative functor syntax—all you need is map
:
implicit val PeopleReads = (__ \ "names").read[Set[Id]].map(People)
And you're done.
来源:https://stackoverflow.com/questions/21461590/defining-reads-for-json-set-type