Skip to content

fix: support objects in enum keyword#529

Closed
tearfur wants to merge 1 commit into
victools:mainfrom
tearfur:patch-1
Closed

fix: support objects in enum keyword#529
tearfur wants to merge 1 commit into
victools:mainfrom
tearfur:patch-1

Conversation

@tearfur
Copy link
Copy Markdown
Contributor

@tearfur tearfur commented Jun 10, 2025

Adds support for including JSON objects in the enum keyword with withEnumResolver(), as the spec permits this.

https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#name-enum
https://json-schema.org/draft/2019-09/draft-handrews-json-schema-validation-02#rfc.section.6.1.2
https://json-schema.org/draft-07/draft-handrews-json-schema-validation-01#rfc.section.6.1.2
https://json-schema.org/draft-06/draft-wright-json-schema-validation-01#rfc.section.6.23

Elements in the array might be of any type, including null.

I have tested this in my use-case. If there's a better way to do this, feel free to let me know.

@CarstenWickner
Copy link
Copy Markdown
Member

Hi @tearfur,

Two notes:

  1. The use case you described on fix: extract distinct enum values #532 is not a Java enum concern, but the wish to represent permutations of an object's combined properties via the enum schema keyword. The built-in EnumModule however, is meant for handling Java enums and therefore not quite the ideal place to tackle this challenge.
  2. Why support Map as enum type? If you want to bypass the built-in simple enum handling, expecting a JsonNode would be more consistent with the existing option for complex configurations.
  3. Nothing prevents the inclusion of objects in the enum keyword today, i.e., no need to make any code changes here. As the documentation suggests:

    Write your own custom definition provider

You can use the one in the EnumModule as inspiration and achieve what you mentioned on #532 with something like this:

class CodePairDefinitionProvider implements CustomDefinitionProviderV2 {
    private static final String BASE_SCHEMA = "{\"type\":\"object\",\"properties\":{\"firstCode\":{\"type\":\"string\"},\"secondCode\":{\"type\":\"string\"},\"scheme\":{\"type\":\"string\"}}}";
    @Override
    public CustomDefinition provideCustomSchemaDefinition(ResolvedType javaType, SchemaGenerationContext context) {
        if (javaType.isInstanceOf(CodePair.class)) {
            var customNode = context.getGeneratorConfig().getObjectMapper().readTree(BASE_SCHEMA);
            var enumArray = customNode.putArray(context.getKeyword(SchemaKeyword.TAG_ENUM);
            for (SchemeVersion scheme : SchemeVersion.values()) {
                for (FirstCode first : FirstCode.values()) {
                    if (first.getScheme() != scheme) {
                        continue;
                    }
                    for (SecondCode second : SecondCode.values()) {
                        if (second.getScheme() != scheme) {
                            continue;
                        }
                        var permutation = context.getGeneratorConfig().createObjectNode()
                                .put("firstCode", first.getCode())
                                .put("secondCode", second.getCode())
                                .put("scheme", scheme.name());
                        enumArray.add(permutation);
                    }
                }
            }
            return new CustomDefinition(customNode);
        }
        return null;
    }
}

You can clean this up and streamline it etc., but the above is mainly meant to illustrate the approach anyway.
Long story short: it's already possible, and I don't see the need to change the built-in module, that is intended for something else, to accommodate a use case that can already be covered through configuration.

@tearfur
Copy link
Copy Markdown
Contributor Author

tearfur commented Jun 18, 2025

Your CustomDefinition example was very helpful, thanks!

I will close this PR because I don't need it anymore.

@tearfur tearfur closed this Jun 18, 2025
@tearfur tearfur deleted the patch-1 branch June 18, 2025 03:39
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