Closed manekovskiy closed 3 months ago
Good catch! I'll get a fix for this out today, with the usual de-duplication logic for name collisions.
One appealing (and frequently recommended) way of creating string enums is not to use enum
at all, but to use
{
"anyOf": [
{ "$ref": "#/$defs/Value1" },
{ "$ref": "#/$defs/Value2" },
{ "$ref": "#/$defs/Value3" }
],
"$defs": {
"Value1": {
"title": "Documentation title Value1",
"description": "Longform documentation for the enum value",
"type": "string",
"const": ""
},
"Value2": {
"title": "Documentation title Value2",
"description": "Longform documentation for the enum value",
"type": "string",
"const": "Foo"
},
"Value3": {
"title": "Documentation title Value3",
"description": "Longform documentation for the enum value",
"type": "string",
"const": "Bar"
}
}
This is the best way to also be able to document the enum
values, and you still get a single Match()
pattern-matching function for consumption.
As you say, the structure is more verbose if you need to explicitly access the const values: (Value1.ConstInstance
, Value2.ConstInstance
) , but it is much better for documentation.
I talk a bit about this in this article https://endjin.com/blog/2024/05/json-schema-patterns-dotnet-numeric-enumerations-and-pattern-matching
Pleasantly surprised by such a quick turnaround. This fix significantly simplifies my work, as I won't have to go through nine circles of hell rewriting an existing schema that people already got used to. Thank you!
Thanks for a really clear bug report!
It is churning through the release process right now. Should be up on nuget in about 15 minutes.
Example of schema that limits allowed value to
""
(empty string) for thefoo
field value:Command to generate schema models:
generatejsonschematypes "empty-string-value-enum-schema.json" --outputPath "." --rootNamespace "TestSchema" --outputRootTypeName "IssueDemonstration"
A field name is missing for the empty string value in the
IssueDemonstration.FooEntity.EnumValues
class:A potential fix would be to emit a well-known name for an empty string value, something like
EmptyString
or "_". The problem with this approach is that we might encounter a case where enum is defined as["", "EmptyString"]
which will cause a naming conflict.I understand that it is very unlikely to devise a good naming strategy for all non-digit or non-letter values. However, perhaps there is room for special treatment of empty string enum values?
A workaround is to use "anyOf" with a "maxLength" constraint for the "empty string" value:
The issue with this workaround is that it produces two times more files and makes it somewhat less intuitive to work with the model because now one needs to use an empty string literals/constants side-by-side with generated enum class values.