2016-07-01 4 views
1

Bei einer Person Klasse mit einem 'intelligenten Konstruktor', dh nur "gültig" Werte in Person#build ein Person werden konstruieren hat:Definition Liest [X], wobei X Privaten Constructor

case class Person private(age: Int) 

object Person { 
    def build(age: Int): Option[Person] = 
    if (age >= 0 && age <= 125) Some(Person(age)) else None  
} 

ich ein Reads[Person] erstellt, indem es in die Person ‚s Begleitobjekt:

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 

    implicit val reads: Reads[Person] = 
    (__ \ 'age).read[Int].map(a => 
    Person.build(a).getOrElse(throw new RuntimeException("invalid age")    
    ) 

gibt es einen besseren Weg? Ich würde es vorziehen, die Ausnahme zu vermeiden, wenn es möglich ist.

+0

Warum verwenden Sie keine Fallklasse Person (Alter: Int) {require (Alter> = 0 && Alter <= 125, "ungültiges Alter")}? – Simon

+0

Um Ausnahmen zu vermeiden, d. H. Monaden über Ausnahmen verwenden –

+0

Was ist mit der Definition der Reads im Companion-Objekt? – pedrofurla

Antwort

2

Wenn Sie könnten Sie das Spiel funktionalen Stil fallen nutzen die JsResult Monade sind bereit:

new Format[Person] { 
    override def writes(o: Person): JsValue = ??? 

    override def reads(json: JsValue): JsResult[Person] = { 
    try{ 
     json.as[JsObject].value.get("age") 
     .flatMap(age => Person.build(age.as[Int])).map(JsSuccess(_)) 
     .getOrElse(JsError("wrong age")) 
    } catch { 
     case e: Exception => 
     JsError("wrong age") 
    } 
    } 
} 

val person = Json.toJson(Person.build(30)) 

val parsed: \/[String, Person] = person.validate[Person].map(\/-(_)).getOrElse(-\/("some bad request")) 

So ist es ein bisschen komplizierter, als ich in meinem Kommentar vorgeschlagen, aber im Grunde kann man das Parsen in eine wickeln Methode, die eine JsSuccess in eine rechte und eine JsError nach links konvertiert, die try/catch ich benutze, um den Fall zu fangen, in dem der gesendete JSON kein Objekt ist, sondern nur ein Wert oder im Fall das Alter Feld ist keine ganze Zahl.

Verwandte Themen