-
Notifications
You must be signed in to change notification settings - Fork 5
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
Just-in-time-decoded types #413
Conversation
This reverts commit ca92702.
Defn.Type( | ||
List(Mod.Opaque()), | ||
Type.Name(name), | ||
Nil, | ||
extending.fold[Type](t"_root_.io.circe.Json")(name => Type.Name(name)), | ||
Type.Bounds(None, extending.map(name => Type.Name(name))) | ||
) |
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.
Can't use quasi-quotes here unfortunately.
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.
Understood. Also, bummer. Maybe add a comment with this?
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.
I hadn't followed-up on the issue, looks like it may be fixed soon (or possibly already in the latest release). Will check.
@@ -497,11 +544,17 @@ trait Generator { | |||
def valName(prefix: String): Pat.Var = Pat.Var(Term.Name(s"$prefix$name")) | |||
|
|||
val eqDef = Option.when(catsEq)( | |||
q"implicit val ${valName("eq")}: cats.Eq[$n] = cats.Eq.fromUniversalEquals" | |||
if (jitDecoder) | |||
q"implicit val ${valName("eq")}: cats.Eq[$n] = _root_.io.circe.Json.eqJson.asInstanceOf[cats.Eq[$n]]" |
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.
Maybe summon[Eq[Json]]
in case it changes name?
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.
That's pretty much what I did at first 😅 the problem is, the compiler can't distinguish the opaque type from Json
, so summon[Eq[Json]
ends up attempting to circularly summon the very implicit we are defining 😂
in case it changes name?
This would be binary-breaking anyway, so unlikely.
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.
I see. I guess we could summon it once per file and assign it a name ourselves. But may be overkill.
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.
Looks awesome, thank you.
I'm going to close this issue for the time being. |
This implements an alternate code generation scheme, targeting Scala 3.
Instead of generating case classes,
opaque type
s are used that are backed by CirceJson
. Thenextension
methods expose the fields of the type. Behind-the-scenes, these are implemented by "just-in-time" (JIT) decoding of that field to its type.This has some limitations, including:
Json
. Anyway, opaque sum type cannot be sealed, it's not really a sum type at all anymore. This can be mitigated by adding afold
-like operation to the parent type.It should be possible to mix JIT-decoded types with members that are user-defined classes, and vice versa. This is because everything works in terms of
Decoder
s, the only question is when thedecode
happens. The decoder for a JIT-decoded type is the identity functionJson => Json
, and further decoding is deferred till field access.