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

io.circe.generic.extras.decoding.EnumerationDecoder.scala Maven / Gradle / Ivy

There is a newer version: 0.12.0-M3
Show newest version
package io.circe.generic.extras.decoding

import io.circe.{ Decoder, DecodingFailure, HCursor }
import shapeless.{ :+:, CNil, Coproduct, HNil, Inl, Inr, LabelledGeneric, Witness }
import shapeless.labelled.{ field, FieldType }

abstract class EnumerationDecoder[A] extends Decoder[A]

final object EnumerationDecoder {
  implicit val decodeEnumerationCNil: EnumerationDecoder[CNil] = new EnumerationDecoder[CNil] {
    def apply(c: HCursor): Decoder.Result[CNil] = Left(DecodingFailure("Enumeration", c.history))
  }

  implicit def decodeEnumerationCCons[K <: Symbol, V, R <: Coproduct](implicit
    wit: Witness.Aux[K],
    gv: LabelledGeneric.Aux[V, HNil],
    dr: EnumerationDecoder[R]
  ): EnumerationDecoder[FieldType[K, V] :+: R] = new EnumerationDecoder[FieldType[K, V] :+: R] {
    def apply(c: HCursor): Decoder.Result[FieldType[K, V] :+: R] =
      c.as[String] match {
        case Right(s) if s == wit.value.name => Right(Inl(field[K](gv.from(HNil))))
        case Right(_) => dr.apply(c).right.map(Inr(_))
        case Left(err) => Left(DecodingFailure("Enumeration", c.history))
      }
  }

  implicit def decodeEnumeration[A, Repr <: Coproduct](implicit
    gen: LabelledGeneric.Aux[A, Repr],
    rr: EnumerationDecoder[Repr]
  ): EnumerationDecoder[A] =
    new EnumerationDecoder[A] {
      def apply(c: HCursor): Decoder.Result[A] = rr(c).right.map(gen.from)
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy