title: How to create custom encoding of Option types with Circe?
body: <p>It's possible to have a class that looks like so:</p>
  
  <pre><code>case class Amount(value: Int)
  case class Data(insurance: Option[Amount], itemPrice: Amount)
  </code></pre>
  
  <p>If <code>insurance = None</code> it should get a default value of <code>waived: true</code></p>
  
  <p>E.g:</p>
  
  <pre><code>Data(Some(123),100).asJson
  
  // output
  {
    "insurance": {
      "value": 123
    },
    "price": 100
  }
  
  And when no Insurance is opted for:
  
  Data(None,100).asJson
  
  // output
  {
    "insurance": {
      "waived: true
    },
    "price": 100
  }
  </code></pre>
  
  <p>How can this fine-grained control be achieved? I tried various tricks with <code>forProduct2</code> and <code>mapJsonObject</code> but couldn't get it to behave right:</p>
  
  <pre><code>implicit val testEncoder = deriveEncoder[Option[Amount]].mapJsonObject(j =&gt; {
  
      val x = j("Some") match {
        case Some(s) =&gt; // need to convert to [amount -&gt; "value"]
        case None =&gt; JsonObject.apply(("waived",Json.fromBoolean(true)))
      }
  
      x
    })
  </code></pre>
  
  <p>This can easily get me the <code>waived:true</code> part but no idea how to handle the <code>Some(s)</code> case. </p>