nuttycom/xenomorph

Make coproduct syntax a bit nicer

Fristi opened this issue · 0 comments

val roleSchema: Schema[JSchema, Role] = Schema.oneOf(
  alt[JSchema, Role, User.type](
    "user", 
    Schema.const(User),
    User.prism
  ) ::
  alt[JSchema, Role, Administrator](
    "administrator", 
    rec(
      ^(
        required("department", jStr, Administrator.department.asGetter),
        required("subordinateCount", jInt, Administrator.subordinateCount.asGetter)
      )(Administrator.apply _)
    ),
    Administrator.prism
  ) :: shapeless.HNil
)

Which is quite verbose, what could we do to make this more concise and for instance inference work for us?

In my Avro library describing data types it's usually written as:

  private val dateDeselected: Avro[BookingProcess.DateSelected] =
    record2("formulation", "DateSelected")(BookingProcess.DateSelected.apply)(
      "disc" -> member(int.discriminator(1), _.disc),
      "datetime" -> member(localDateTime, _.datetime)
    )

  private val notStarted: Avro[BookingProcess.NotStarted] =
    record1("formulation", "NotStarted")(BookingProcess.NotStarted.apply)(
      "disc" -> member(int.discriminator(0), _.disc)
    )

  private val cancelled: Avro[BookingProcess.Cancelled] =
    record1("formulation", "Cancelled")(BookingProcess.Cancelled.apply)(
      "disc" -> member(int.discriminator(2), _.disc)
    )

  implicit val codec: Avro[BookingProcess] =
    (dateDeselected | notStarted | cancelled).as[BookingProcess]