-
Notifications
You must be signed in to change notification settings - Fork 28
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
Pull semi-auto derivation into a trait, similar to auto derivation #220
base: main
Are you sure you want to change the base?
Conversation
@zmccoy any thoughts here? Thanks! |
@dvgica Sorry for the late review. The code itself looks fine, but we need to update with the latest from main, and fix the mima issues:
|
Thanks @zarthross. I merged main. For the mima issues, do you mean just to filter them? I'm a little unfamiliar with mima but it seems like the issues it's flagging are maybe not legit. To the user,
I guess I'm not sure whether moving |
Unfortunately, I don't have any reason to think Mima is wrong here... your change is 100% source compatible, but the way Scala tends to organize things into jvm bytecode differs sometimes depending on how the code is written. The real problem appears to be how I'm not 100% sure what the best solution here is but,
@isomarcte Is also very good with binary compatibility issues and may have some alternative proposals. |
*/ | ||
def deriveUnwrappedCodec[A](implicit codec: Lazy[UnwrappedCodec[A]]): Codec[A] = codec.value | ||
|
||
final class DerivationHelper[A] { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RE the bincompat issues.
If you define this class inside a non-static context, you are going to create a few issues. While it likely won't commonly come into play, every distinct subtype of trait SemiAutoDerivation
will yield a distinct type DerivationHelper
, because the type of type defined inside a class is scoped to the concrete instance of said class.
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait Foo {
case object Bar
}
object A extends Foo
object B extends Foo
// Exiting paste mode, now interpreting.
trait Foo
object A
object B
scala> implicitly[A.Bar.type =:= A.Bar.type]
val res3: A.Bar.type =:= A.Bar.type = generalized constraint
scala> implicitly[B.Bar.type =:= A.Bar.type]
^
error: Cannot prove that B.Bar.type =:= A.Bar.type.
=:=
is how we can ask the compiler to prove type equivalence.
Also, with respect to the bincompat issues that @zarthross mentioned, many of them are caused by you moving this type into this trait.
For bincompat, you need to move DerivationHelper
back into object semiauto
.
My suggestion for this series would be to have this trait proxy to semiauto
and then not have semiauto
implement it. The in the next series, pull DerivationHelper
into its own file, and reimplement this the way you have it now.
Sorry, bincompat stuff is always a pain. There are other much more verbose options we could do in this series, but I question their merit given this isn't a lot of code.
@zarthross @dvgica thoughts?
This is useful when you're trying to build an object that has a bunch of Circe config and implicits, such that you can use a single import to bring them all into scope. It avoids needing the extra
io.circe.generic.extras.semiauto._
import.Similar idea to https://tapir.softwaremill.com/en/latest/mytapir.html and consistent with
AutoDerivation
. I tried makingsemiauto
into a package object for consistency withauto
, but had a bit of trouble due to this line so left it as just an object.Previous import usage will still work.