Skip to content

feat: transientNull option support #1307

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

Merged
merged 2 commits into from
Jul 23, 2025

Conversation

Dolfik1
Copy link
Contributor

@Dolfik1 Dolfik1 commented Jul 23, 2025

Introduces a new transientNull flag to CodecMakerConfig, allowing users to exclude fields with null values from JSON output. The flag is disabled by default to preserve existing behavior.

Also adds related logic in the macro and a test suite (JsonCodecMakerNullableSpec) to verify serialization with and without transientNull enabled.

@plokhotnyuk
Copy link
Owner

plokhotnyuk commented Jul 23, 2025

@Dolfik1 Thanks for the contribution!

Could you please share your use case?

Is it about migration from Circe to jsoniter-scala and that is why your propose transientNull = true in makeCirceLikeSnakeCased?

Have you considered to make similar improvements for Scala 2 macros?

@Dolfik1
Copy link
Contributor Author

Dolfik1 commented Jul 23, 2025

@plokhotnyuk First of all, thank you for this great library!

Could you please share your use case?

In our project, we frequently use nullable types YYY | Null instead of Option[YYY]. This also applies to types that are serialized into JSON using jsoniter-scala. Unfortunately, there was no way to configure the behavior so that fields with null values are excluded from the final JSON. That's why I added support for such types, similar to how transientNone works.

Is it about migration from Circe to jsoniter-scala and that is why your propose transientNull = true in makeCirceLikeSnakeCased?

No, it's not related to Circe. I just followed the approach used for transientNone.

Have you considered to make similar improvements for Scala 2 macros?

I'm not very familiar with Scala 2, but as far as I understand, union types are not supported there, so it may not be directly applicable.

@plokhotnyuk
Copy link
Owner

plokhotnyuk commented Jul 23, 2025

Am I understand right that the configuration option should be limited for Null types only?

If yes, then how about using the following implementation instead?

      def isNullable(tpe: TypeRepr): Boolean = tpe match {
        case OrType(left, right) => isNullable(right) || isNullable(left)
        case _ => tpe =:= TypeRepr.of[Null]
      }

It will fix remaining test failures and extend this feature for all union types including nested ones like String | Null | Boolean | Double.

Also, increasing the minor version (in the ./version.sbt) is the remaining one requirement to pass MiMa checks.

@Dolfik1
Copy link
Contributor Author

Dolfik1 commented Jul 23, 2025

Am I understand right that the configuration option should be limited for Null types only?

If yes, then how about using the following implementation instead?

      def isNullable(tpe: TypeRepr): Boolean = tpe match {
        case OrType(left, right) => isNullable(right) || isNullable(left)
        case _ => tpe =:= TypeRepr.of[Null]
      }

It will fix remaining test failures and extend this feature for all union types including nested ones like String | Null | Boolean | Double.

Also, increasing the minor version (in the ./version.sbt) is the remaining one requirement to pass MiMa checks.

Thank you for your feedback. I've fixed it.

@plokhotnyuk plokhotnyuk merged commit fbdd283 into plokhotnyuk:master Jul 23, 2025
0 of 4 checks passed
@plokhotnyuk
Copy link
Owner

@Dolfik1 Please peek the latest release with your new compile-time option.

It is already available on the Maven Central.

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.

2 participants