title: how to represent a JSON as a case class
body: <p>I want to represent a JSON as a case class. </p>
  
  <pre><code>{
  result:"success" or "fail"
  message: "some message"
  }
  </code></pre>
  
  <p>My particular requirement is that <code>result</code> should only take values "success" or "error". Any other value should fail parsing of the JSON</p>
  
  <p>I tried creating a trait and then sub-classing it but I don't understand how to restrict the values of <code>result</code></p>
  
  <pre><code>sealed trait JSONResult 
  
  case class JSONResultError(final val result:String="error") extends JSONResult
  case class JSONResultSuccess(final val result:String="success") extends JSONResult
  
  case class JsonMessages (
                          result: JSONResult,
                          message: String
                          )
  </code></pre>
  
  <p>Though I could create a variable of type JsonMEssages, I cannot distinguish whether result is of type <code>JSONResultSuccess</code> or <code>JSONResultError</code>.  </p>
  
  <pre><code>scala&gt; val jm = JsonMessages(JSONResultError(),"some error message")
  jm: JsonMessages = JsonMessages(JSONResultError(error),some error message)
  
  scala&gt;scala&gt; jm.result.result //this doesn't work because result is of type JSONResult which hasn't got `result` though it holds object of type `JSONResultError`
  &lt;console&gt;:13: error: value result is not a member of JSONResult
         jm.result.result
                   ^
  
  scala&gt; jm.result
  res17: JSONResult = JSONResultError(error)
  </code></pre>
  
  <p>Eventually, I would like to be able to create a <code>Reads</code> or <code>Writes</code> as follows but I am not confident that this would work.</p>
  
  <pre><code>object JSONMessagesImplicits {
  
    /*Writes (write to JsValue) are used by toJson method of Json object to convert data (say the model) to JsValue*/
  
    implicit val JsonResultErrorWrites: Writes[JSONResultError] = (JsPath \ "result").write[String](unlift(JSONResultError.unapply))
    implicit val JsonResultSuccessWrites: Writes[JSONResultSuccess] = (JsPath \ "result").write[String](unlift(JSONResultError.unapply))
  
    implicit val JsonMessagesWithErrorWrites: Writes[JsonMessages] = (
      (JsPath \ "result").write[JSONResultError] and
        (JsPath \ "message").write[String]) (unlift(JsonMessages.unapply))
  
    implicit val JsonMessagesWithSuccessWrites: Writes[JsonMessages] = (
      (JsPath \ "result").write[JSONResultSuccess] and
        (JsPath \ "message").write[String]) (unlift(JsonMessages.unapply))
  }
  </code></pre>