circe trait継承クラスのEncoder/Decoder

## circe概要
- Scalaの純粋関数型Jsonライブラリ

## encoder decoder定義するケース
- generic.autoでは対応できない場合
- 下記```ContentList```要素```value```をjsonの階層に含めたくない場合
- 出力項目をカスタマイズ
- trait継承クラスの識別条件カスタマイズ


>For large or deeply-nested case classes and sealed trait hierarchies, the generic derivation provided by the generic subproject may stack overflow during compilation, which will result in the derived encoders or decoders simply not being found. Increasing the stack size available to the compiler (e.g. with sbt -J-Xss64m if you’re using SBT) will help in many cases, but we have at least one report of a case where it doesn’t. It might be simpler and safer to add .sbtopts file with SBT parameters (-J-Xss64m) in root of project.

circe versoin : 0.10.0

```
object main extends App {

  import io.circe.{Encoder, Decoder, HCursor, Json}
  import io.circe.parser._
  import io.circe.generic.auto._

  case class ContentList(value:Seq[BaseTrait])
  object ContentList {
    implicit val encoder: Encoder[ContentList] = Encoder[Seq[BaseTrait]].contramap(_.value)
    implicit val decoder: Decoder[ContentList] = Decoder[Seq[BaseTrait]].map(ContentList(_))
  }

  sealed trait BaseTrait {
    val classType:String
  }
  object BaseTrait {
    implicit val encoder: Encoder[BaseTrait] = new Encoder[BaseTrait] {
      // don't do r.asJson for avoiding from possibility of stack overflow
      override final def apply(r: BaseTrait): Json = {
        r match {
          case a:A => a.asJson
          case b:B => b.asJson
          case c:C => c.asJson
        }
      }
    }
    implicit val decoder: Decoder[BaseTrait] = for {
      classType <- Decoder[String].prepare(_.downField("classType"))
      value <- classType match {
        case "A" => Decoder[A]
        case "B" => Decoder[B]
        case "C" => Decoder[C]
        case _ => Decoder.failedWithMessage("invalid classType")
      }
    } yield value

    case class A (valueStr:String) extends BaseTrait {
      override val classType: String = "A"
    }
    object A {
      // Note this encoder for encode classType of trait
      implicit val encoder: Encoder[A] = new Encoder[A] {
        override final def apply(r: A): Json = Json.obj(
          "classType" -> Json.fromString(r.classType),
          "valueStr" -> Json.fromString(r.valueStr)
        )
      }
    }

    case class B (valueStr:String) extends BaseTrait {
      override val classType: String = "B"
    }
    object B {
      implicit val encoder: Encoder[B] = new Encoder[B] {
        override final def apply(r: B): Json = Json.obj(
          "classType" -> Json.fromString(r.classType),
          "valueStr" -> Json.fromString(r.valueStr)
        )
      }
    }

    case class C (valueInt:Int) extends BaseTrait {
      override val classType: String = "C"
    }
    object C {
      implicit val encoder: Encoder[C] = new Encoder[C] {
        override final def apply(r: C): Json = Json.obj(
          "classType" -> Json.fromString(r.classType),
          "valueInt" -> Json.fromInt(r.valueInt)
        )
      }
    }
  }


  val jsonString = """[{"classType" : "A", "valueStr" : "A value"}, {"classType" : "B", "valueStr" : "B value"}, {"classType" : "C", "valueInt" : 1}]"""
  val decodedClass = decode[ContentList](jsonString).right.get
  val encodedJson = decodedClass.asJson
  decodedClass
```

### 備考
BaseTrait継承クラスがAとCだけの場合、class内容が異なる為、下記定義が可能

```
implicit val decode: Decoder[BaseTrait] = {
  Decoder[A].map[BaseTrait](identity)
  .or(Decoder[C].map[BaseTrait](identity))
}
```