2016-09-08 8 views
4

のためのScalaのJSONフォーマットは私がのためのScalaのv2.5.6のJSON Formatのためのプレイを生成したいEitherを、受け入れる値クラスを持っています方法が分かった。私が抱えている問題はreadsメソッドです。私は2つのアプローチを試みましたが、どちらも異なる理由で失敗しました。再生/どちらか

import play.api.libs.json._ 
import play.api.libs.json.Json.obj 

object When {  
    def apply(dateTime: DateTime): When = When(Left(dateTime)) 

    def apply(duration: Duration): When = When(Right(duration)) 

    implicit val whenFormat = new Format[When] { 
    def reads(json: JsValue): JsResult[When] = { 
     val reads = (__ \ "dateTime").read[Long] { (millis: Long) => 
     When(Left(new DateTime(millis))) 
     } | (__ \ "duration").read[Long] { (millis: Long) => 
     When(Right(new Duration(millis))) 
     } 
     reads.reads(json) 
    } 

    def writes(o: When): JsValue = obj(
     o.when.fold(
     duration => "duration" -> duration.getMillis, 
     dateTime => "dateTime" -> dateTime.getMillis 
    ) 
    ) 
    } 
} 

エラーメッセージは次のとおり:

overloaded method value read with alternatives: 
[error] (t: Long)play.api.libs.json.Reads[Long] <and> 
[error] (implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.Reads[Long] 
[error] cannot be applied to (Long => When) 
[error]  val reads = (__ \ "dateTime").read[Long] { (millis: Long) => 

[error] overloaded method value read with alternatives: 
[error] (t: Long)play.api.libs.json.Reads[Long] <and> 
[error] (implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.Reads[Long] 
[error] cannot be applied to (Long => When) 
[error]  } | (__ \ "duration").read[Long] { (millis: Long) => 

試み#2、ちょうどreads方法を示す:

def reads(json: JsValue): JsResult[When] = 
    JsSuccess(
    When(Left(new DateTime((__ \ "dateTime").read[Long]))) || 
    When(Right(new Duration((__ \ "duration").read[Long]))) 
) 
readswrites方法の両方を示す

試み#1、

エラーメッセージ:

value || is not a member of When 
[error] Note: implicit value whenFormat is not applicable here because it comes after the application point and it lacks an explicit result type 
[error] Error occurred in an application involving default arguments. 

私はちょうどうまくいくものが好きですし、維持可能で効率的である限り、どのアプローチが使用されても気にしません。これらのアプローチのそれぞれで何が間違っていたのかを知ることも役立ちます。ここで

+0

'When'から' extends AnyVal'を削除しようとしました –

+0

'extends AnyVal'を削除するといずれの方法とも違いはありません –

答えて

5

はこれを行う方法の実施例である:

import org.joda.time.{DateTime, Duration} 
import play.api.libs.functional.syntax._ 
import play.api.libs.json.Reads._ 
import play.api.libs.json._ 

object When { 
    def apply(dateTime: DateTime): When = When(Left(dateTime)) 

    def apply(duration: Duration): When = When(Right(duration)) 

    val reads: Reads[When] = 
    (__ \ "dateTime").read[Long].map(millis => When(Left(new DateTime(millis)))) | 
    (__ \ "duration").read[Long].map(millis => When(Right(new Duration(millis)))) 

    val writes: Writes[When] = new Writes[When] { 
    override def writes(o: When): JsValue = Json.obj(
     o.when.fold(
     duration => "duration" -> duration.getMillis, 
     dateTime => "dateTime" -> dateTime.getMillis 
    ) 
    ) 
    } 

    implicit val format = Format(reads, writes) 
} 

基本的にあなたが

(__ \ "dateTime").read[Long] 

は、あなたがWhenにつながるマッピングすることができ、あなたにReads[Long]を与える読み込むマップする必要があります。あなたはパラメータを渡すだけでした。このパラメータはLongになり、読み取られた内容を無視してその値を返すか、またはimplicitは長い間読み込み、変更したくない可能性があり、暗黙的にしておく必要があります。

同様に、別の読み取り時間を作成し、代替(|)と組み合わせて読み取りを行うことができます。

あなたの2番目のアプローチは意味をなさない。読み取りと作成を使用するか、手動で何かが存在するかどうかを確認し、異なる結果を返さない場合は、これを行う価値はありません。デフォルトの方法で行ってください。

+0

パーフェクト!私はあなたの答えを容認された解決策にしました。ところで、あなたが表示するコードの最初の行が不適切にフォーマットされています。 –

+0

おっと、私はあまりにも早く受け入れました。 |演算子は未定義です。 –

+0

構文をインポートする必要があります。更新を参照してください。私は書式も修正しました。ありがとうございました。 –