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

Extension of JsonCodec to have parity features with generic.extra #91

Closed
wants to merge 9 commits into from

Conversation

aparo
Copy link
Contributor

@aparo aparo commented Aug 12, 2019

The implementation allows to:

  • use JsonCodec with JsonKey annotation to have custom keys
  • use default values in case of missing values in serialization
  • disable the serialization of a vaue using JsonNoDefault() annotation
  • serialize an ADT if all the subclasses are circe codec serializable/deseriable using JsonCodec macro.

I closes #8 and #24

Copy link
Member

@travisbrown travisbrown left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really great! I've got a few comments but I'm excited to get this merged and released as soon as possible.


if (noSerializeDefault && defaultValue.isDefined) {
q"""
if(a.$name==${defaultValue.get}) None else
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mind putting the prefixes on None and Some for the sake of hygiene?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you better explain the change that you want? Witch prefix?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that if the user has a different None definition at the macro use site, it'll get used instead of scala.None.

sealed trait Discriminator

object Discriminator {
final case class Embedded(fieldName: String) extends Discriminator
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In circe-generic-extras we tend to use "type field" and "object wrapper" to refer to these approaches. I don't feel too strongly about this, but I think we should standardize one way or the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's me check and apply the same approach

final case class Embedded(fieldName: String) extends Discriminator
final case object TypeDiscriminator extends Discriminator

lazy val default = Embedded("type")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking again, but can you put a type annotation on this, both for documentation and so it's not inferred to be Embedded?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also for something like this I think the overhead of lazy val probably outweighs any benefits of deferring the instantiation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I used the lazy val to be sure to no have concurrency problem in initialization of the value

val tpe = weakTypeOf[T]

// Valid only in macro!!
val globalUseDefaults: Boolean = extractUseDefaults(useDefaults.tree)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about the name here. In what sense is it global?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll rename in useDefaults

@travisbrown
Copy link
Member

I think the failure is just Scalafmt—sbt scalafmt should fix it.


/** Configuration allowing customisation of JSON produced when encoding or
* decoding.
*
* This configuration creates *both* encoder and decoder.
*/
final case class Codec(
transformMemberNames: String => String
transformMemberNames: String => String,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we support ADTs we should probably have transformConstructorNames as well, but I can add that in a follow-up.

@travisbrown
Copy link
Member

We will want to do some benchmarking to ensure that this doesn't impose a compile-time cost on the use cases we support now, but we can worry about that later.

@travisbrown
Copy link
Member

Oh, you also need sbt test:scalafmt (and possibly sbt scalafmtSbt?).

@@ -87,11 +87,11 @@ private[derivation] final class GenericJsonCodecMacros(val c: blackbox.Context)

private[this] def codecFrom(tree: Tree): JsonCodecType =
tree.tpe.dealias match {
case t if t <:< typeOf[Configuration.Codec] =>
case t if t == typeOf[Configuration.Codec] =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

equals is not guaranteed to work correctly on scala-reflect types. Maybe =:=?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, I hadn't noticed these changes. @aparo, is there a reason to change these? I fixed this a few weeks ago because I was getting inaccurate warnings in some contexts.

@travisbrown
Copy link
Member

Merging this, and will address remaining issues in a follow-up. Thanks again so much, @aparo!

@travisbrown
Copy link
Member

Oh, there's a merge conflict. I'll pull these commits into a new PR.

@travisbrown
Copy link
Member

Included in #100.

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

Successfully merging this pull request may close these issues.

Support sealed trait hierarchies
3 participants