schemars icon indicating copy to clipboard operation
schemars copied to clipboard

Documenting enum variants

Open ThouCheese opened this issue 4 years ago • 7 comments

Currently, doc comments on enum variants are ignored.

/// An enum representing the kind of the thing.
#[derive(schemars::JsonSchema)]
struct Kind {
    /// The kind is one!
    One,
    /// The kind is two!
    Two,
    /// The kind is not three!
    NotThree,
}

The resulting schema looks like:

"Kind": {
  "type": "string",
  "description": "An enum representing the kind of the thing.",
  "enum": [
    "One",
    "Two",
    "NotThree"
  ]
},

I searched the documentation of openapi, but it doesn't seem that they have proper support for documenting enum variants. I therefore suggest that the generated openapi.json should be something along the lines of

"Kind": {
  "type": "string",
  "description": "An enum representing the kind of the thing. \n\n## Variants \nOne: The kind is one! \nTwo: The kind is two! \nNotThree: The kind is not three!",
  "enum": [
    "One",
    "Two",
    "NotThree"
  ]
},

where we just append the variant documentation to the already existing documentation field, seperated by a newline or two and a header.

ThouCheese avatar May 26 '20 15:05 ThouCheese

I think a better alternative is to do as follows:

oneOf: [
{
"type": {
        "type": "string",
        "const": "VariantA"
},
{
"type": {
        "type": "string",
        "const": "VariantB"
},
]

JeremyRubin avatar Mar 14 '22 16:03 JeremyRubin

tag @GREsau since this is an old issue and he might miss it.

this sort of representation works a tad better because you keep the docs associated with the actual unit, and it prevents the 'agglomeration of unit variants into one enum' generating things like e.g. messy forms.

JeremyRubin avatar Mar 14 '22 16:03 JeremyRubin

That’s what schemars currently generate – oneOf with a type for each enum variant, but with a single-item enum instead of const.

jirutka avatar Aug 27 '23 18:08 jirutka

That’s what schemars currently generate – oneOf with a type for each enum variant, but with a single-item enum instead of const.

This behaviour is not suitable for our use case. Is there a way to disable this to obtain something like

"enum": [
    "One",
    "Two",
    "NotThree"
  ]

keeping the docstring in the rust structs?

dariocurr avatar Sep 26 '23 14:09 dariocurr

I’d like to disable it too.

jirutka avatar Sep 27 '23 00:09 jirutka

As this was making some docs of mine useless to read, I've made a local fix that updates the logic that determines when this changes to oneOf by removing the check for attributes of enum variants. See here. Probably not the best way to go about it, but it at least makes my documented enums readable again.

fn expr_for_external_tagged_enum<'a>(
    variants: impl Iterator<Item = &'a Variant<'a>>,
    deny_unknown_fields: bool,
) -> TokenStream {
    let mut unique_names = HashSet::<String>::new();
    let mut count = 0;
    let (unit_variants, complex_variants): (Vec<_>, Vec<_>) = variants
        .inspect(|v| {
            unique_names.insert(v.name());
            count += 1;
        })
-        .partition(|v| v.is_unit() && v.attrs.is_default());
+        .partition(|v| v.is_unit());

pcleavelin avatar Feb 26 '24 22:02 pcleavelin