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

Allow annotation meta-annotations with Serializable #2741

Open
Chuckame opened this issue Jul 8, 2024 · 0 comments
Open

Allow annotation meta-annotations with Serializable #2741

Chuckame opened this issue Jul 8, 2024 · 0 comments
Labels

Comments

@Chuckame
Copy link
Contributor

Chuckame commented Jul 8, 2024

What is your use-case and why do you need this feature?
Currently, annotating a property with an annotation having MetaSerializable instructs the serialization plugin to treat the annotated data class as serializable.

Doing that onto a field does't instruct the serialization plugin, as it misses the final serializer to be used: contextual ? custom ? something else ?

@MetaSerializable
@SerialInfo
annotation class MyAnnotation(val data: String)

@MyAnnotation("some content") // <-- the data class is treated as Serializable and is accessible from the `SerialDescriptor` annotations
data class MyData(
    @MyAnnotation("some content") // <-- ERROR: Serializer has not been found for type 'MyType' as the serializer needs to be explicit or contextual
    val theField: MyType,
)

Describe the solution you'd like
Allow @Serializable to be put on a meta-annotation, allowing us to unify the serializers with their possible configuration as we cannot pass params because of we need to provide a class.

I'm giving you an example: an avro fixed type requires some details to work properly, like its size in bytes. To configure the serializer to encode the content in 10 bytes, we can do like the following:

@Serializable
data class MyData(
    @Serializable(with = ByteArrayFixedSerializer::class)
    @AvroFixed(size = 10)
    val theField: ByteArray,
)

Or even, more generically, for a given BigDecimal where we allow a maximum precision when encoding to a String:

@Serializable
data class MyData(
    @Serializable(with = BigDecimalStringSerializer::class)
    @DecimalPrecision(digits = 3)
    val theField: BigDecimal,
    @Serializable(with = AnotherDecimalSerializer::class)
    @DecimalPrecision(digits = 3) // <--- This is useless as not handled by the AnotherDecimalSerializer implementation
    val theField2: BigDecimal,
)

At the end, here would be the final code, making it clearer for the users IMO as it reduces the noise of needing many annotations:

@SerialInfo
@MetaSerializable
@Serializable(with = ByteArrayFixedSerializer::class)
annotation class AvroFixed(val size: Int)

@SerialInfo
@MetaSerializable
@Serializable(with = BigDecimalStringSerializer::class)
annotation class DecimalPrecision(val digits: Int)

@Serializable
data class MyData(
    @AvroFixed(size = 10)
    val theBytesField: ByteArray,
    @DecimalPrecision(digits = 3)
    val theDecimalField: BigDecimal,

    @AvroFixed(size = 10)
    @DecimalPrecision(digits = 3)
    val wrongField: BigDecimal,// <--- ERROR: Doesn't compile as we are trying to apply 2 different serializers

    @DecimalPrecision(digits = 3)
    @Serializable(with = AnotherBigDecimalSerializer::class)
    val example1: BigDecimal,// <--- AnotherBigDecimalSerializer takes precedence

    @AvroFixed(size = 10)
    val example1: BigDecimal,// <--- ERROR: Same as explicit `Serializable` annotation, where we are not able to annotate with a serializer of a different type
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant