Skip to content

Conversation

@tearfur
Copy link
Contributor

@tearfur tearfur commented Jun 12, 2025

When using custom EnumModules, sometimes there may be multiple enums resolving to the same value, so make sure they are distinct to reduce the size of the resulting schema.

Copy link
Member

@CarstenWickner CarstenWickner left a comment

Choose a reason for hiding this comment

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

I'd argue there is something going wrong, when multiple enum values are serialized as the same representations in a JSON document, as they then can't be deserialized again afterwards.

On the other hand, the tiny performance degradation for this (normally redundant) distinct() check can probably be accepted.

@CarstenWickner CarstenWickner merged commit 995a71e into victools:main Jun 12, 2025
11 checks passed
@tearfur tearfur deleted the patch-2 branch June 13, 2025 01:01
@tearfur
Copy link
Contributor Author

tearfur commented Jun 13, 2025

Thanks for merging. Let me give some context on why I found myself needing this.

tl:dr I had to implement an encoding scheme that consists of a pair of values, and this scheme had gone through multiple iterations over the years, where some codes are kept as-is in the newer iterations. These codes from the different iterations are what's producing the duplicate values.

Here's some pseudo-code to demonstrate my situation (It's Kotlin because my code is in Kotlin):

enum class SchemeVersion {
    V1,
    V2,
}

interface CodeInterface {
    val code: String
}

enum class FirstCode(
    @JsonValue // com.fasterxml.jackson.annotation.JsonValue
    override val code: String,
    val scheme: SchemeVersion
    val description: String,
) : CodeInterface {
    A_V1("A", SchemeVersion.V1, "Code A, V1"),
    B_V2("B", SchemeVersion.V1, "Code B, V1"),
    A_V2("A", SchemeVersion.V2, "Code A, V2"),
    C_V2("C", SchemeVersion.V2, "Code C, V2"),
}

enum class SecondCode(
    @JsonValue
    override val code: String,
    val scheme: SchemeVersion
    val description: String,
) : CodeInterface {
    X_V1("X", SchemeVersion.V1, "Code X, V1"),
    Y_V2("Y", SchemeVersion.V1, "Code Y, V1"),
    X_V2("X", SchemeVersion.V2, "Code X, V2"),
    Z_V2("Z", SchemeVersion.V2, "Code Z, V2"),
}

I want to serialise the code to a JSON object like this (this is FirstCode.A_V1 + SecondCode.Y_V1):

{
  "firstCode": "A",
  "secondCode": "Y",
  "scheme": "V1"
}

So I represented them in my entity object like this:

class CodePair(
    val firstCode: FirstCode,
    val secondCode: SecondCode,
    val scheme: SchemeVersion,
)

class Entity (
    // ...
    val code: CodePair,
    // ...
)

Now, the "proper" way to define Entity::code in the schema would probably be to list all of the possible permutations of valid CodePair values, since not all combinations of firstCode and secondCode are valid:

{
  "type": "object",
  "properties": {
    "firstCode": { "type": "string" },
    "secondCode": { "type": "string" },
    "scheme": { "type": "string" }
  },
  "enum": [
    { "firstCode": "A", "secondCode": "X", "scheme": "V1" },
    { "firstCode": "A", "secondCode": "Y", "scheme": "V1" },
    // ...
  ]
}

But this is not possible in this library, which is why I raised #529. And for the meantime I configured my schema builder with a custom EnumModule like this:

configBuilder.with(EnumModule { v ->
    if (v is CodeInterface)
        v.code
    else
        v.name
})

And that's how I ended up with duplicate values in the schema enum array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants