zio / zio-json

Fast, secure JSON library with tight ZIO integration.
https://zio.dev/zio-json
Apache License 2.0
409 stars 146 forks source link

Implement auto deriving without `derives` clause for scala 3 #624

Open liewhite opened 2 years ago

liewhite commented 2 years ago

Like circe:

import io.circe.generic.auto._

If we could do this. There will be less boilerplate code. For example , use tapir to generate openapi, if i use zio-json as json plugin, i have to write at least 10+ gen statement. I tried to add auto deriving with

 inline given [T: Mirror.Of]: JsonCodec[T] = DeriveJsonCodec.gen[T]

but get a compile error infinite inline loops on recursive structure.

fsvehla commented 2 years ago

Most likely releated: https://github.com/lampepfl/dotty/issues/8183

liewhite commented 2 years ago

Most likely releated: lampepfl/dotty#8183

This might has been solved. Use by name param in product and sum.

def eqSum[T](s: Mirror.SumOf[T], elems: => List[Eq[_]]): Eq[T] =
    new Eq[T]:
      def eqv(x: T, y: T): Boolean =
        val ordx = s.ordinal(x)
        (s.ordinal(y) == ordx) && check(elems(ordx))(x, y)

  def eqProduct[T](p: Mirror.ProductOf[T], elems: => List[Eq[_]]): Eq[T] =
    new Eq[T]:
      def eqv(x: T, y: T): Boolean =
        iterator(x).zip(iterator(y)).zip(elems.iterator).forall {
          case ((x, y), elem) => check(elem)(x, y)
        }

  inline given derived[T](using m: Mirror.Of[T]): Eq[T] =
    lazy val elemInstances = summonAll[m.MirroredElemTypes]
    inline m match
      case s: Mirror.SumOf[T]     => eqSum(s, elemInstances)
      case p: Mirror.ProductOf[T] => eqProduct(p, elemInstances)

It seems magnolia does not handle recursive types : https://github.com/softwaremill/magnolia/blob/4833c84b83f728165d672d0c32ac1e5c469a42d2/src/core/magnolia.scala#L164-L167

dylandoamaral commented 1 year ago

Hi do you have a work around to deal with recursive types in Scala 3 ?

liewhite commented 1 year ago

Hi do you have a work around to deal with recursive types in Scala 3 ?

I build a codec layer on circe here liewhite/json

guizmaii commented 1 year ago

If the request is to bring the Circe import io.circe.generic.auto._ magic to zio-json, I'm pretty much against this request. It makes your code very fragile and is an anti-pattern IMO