All Downloads are FREE. Search and download functionalities are using the official Maven repository.

api4s.codegen.emitter.CirceModel.scala Maven / Gradle / Ivy

There is a newer version: 0.3.1.1
Show newest version
package api4s.codegen.emitter

import api4s.codegen.ast.Type._
import api4s.codegen.ast._
import api4s.codegen.emitter.Utils.default._

object CirceModel {
  def apply(pkg: String, ts: Map[String, Type]): String = {
    val defs = ts
      .map { case (n, t) => typeDef(n, t).map("  " + _).mkString("\n") }
      .mkString("\n")
    val codecs = ts.map {
      case (n, TObj(_)) => List(
        s"  implicit val encoderOf$n: Encoder[$n] = deriveEncoder",
        s"  implicit val decoderOf$n: Decoder[$n] = deriveDecoder"
      )
      case _ => Nil
    }.filter(_.nonEmpty).map(_.mkString("\n")).mkString("\n\n")
    List(
      s"package $pkg",
      "",
      "import io.circe.{ Decoder, Encoder, Json }",
      "import io.circe.generic.semiauto._",
      "",
      "object Model {",
      defs,
      "",
      codecs,
      "}"
    ).mkString("\n")
  }

  private def typeDef(n: String, t: Type): List[String] = t match {
    case TObj(fields) =>
      val fieldStrs = fields.map {
        case (n, Field(t @ TArr(_), _, true)) => s"  $n: ${typeStr(t)} = Nil"
        case (n, Field(t, _, true)) => s"  $n: ${typeStr(t)}"
        case (n, Field(t, _, false)) => s"  $n: Option[${typeStr(t)}] = None"
      }.toList match {
        case Nil => Nil
        case List(e) => List(e)
        case l2 =>
          val rev = l2.reverse
          (rev.head :: rev.tail.map(_ + ",")).reverse
      }
      s"case class $n(" :: fieldStrs ++ List(")")
    case _ => List(s"type $n = ${typeStr(t)}")
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy