Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement auto deriving without derives clause for scala 3 #624

Open
liewhite opened this issue Apr 23, 2022 · 5 comments
Open

Implement auto deriving without derives clause for scala 3 #624

liewhite opened this issue Apr 23, 2022 · 5 comments

Comments

@liewhite
Copy link

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.

@liewhite liewhite changed the title Implement auto deriving without derives clause Implement auto deriving without derives clause for scala 3 Apr 23, 2022
@fsvehla
Copy link
Contributor

fsvehla commented Apr 25, 2022

Most likely releated: scala/scala3#8183

@liewhite
Copy link
Author

liewhite commented Apr 25, 2022

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
Copy link

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

@liewhite
Copy link
Author

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
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants