Skip to content

Getting empty enum with allOf of oneOfsΒ #897

@PolyProgrammist

Description

@PolyProgrammist

Getting empty enum with allOfs of oneOfs

For this schema:

{
  "openapi": "3.0.0",
  "info": {
    "title": "NEAR Protocol JSON RPC API",
    "version": "1.1.2"
  },
  "paths": {},
  "components": {
    "schemas": {
      "MyStruct": {
        "allOf": [
          {
            "oneOf": [
              {
                "properties": {
                  "myfirsttag": {
                    "enum": [
                      "a"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "myfirsttag"
                ],
                "type": "object"
              },
              {
                "format": "uint64",
                "minimum": 0,
                "properties": {
                  "myfirsttag": {
                    "enum": [
                      "b"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "myfirsttag"
                ],
                "type": "object"
              }
            ]
          },
          {
            "oneOf": [
              {
                "properties": {
                  "mysecondtag": {
                    "enum": [
                      "c"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "mysecondtag"
                ],
                "type": "object"
              },
              {
                "format": "uint64",
                "minimum": 0,
                "properties": {
                  "mysecondtag": {
                    "enum": [
                      "d"
                    ],
                    "type": "string"
                  }
                },
                "required": [
                  "mysecondtag"
                ],
                "type": "object"
              }
            ]
          }
        ],
        "title": "MyStruct",
        "type": "object"
      }
    }
  }
}

The output is:

    #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)]
    #[serde(untagged)]
    pub enum MyStruct {
        Variant0(MyStructVariant0),
        Variant1(MyStructVariant1),
    }

    #[derive(:: serde :: Deserialize, :: serde :: Serialize, Clone, Debug)]
    #[serde(untagged)]
    pub enum MyStructVariant0 {
        Variant0(MyStructVariant0Variant0),
        Variant1(MyStructVariant0Variant1),
    }

    #[serde(deny_unknown_fields)]
    pub enum MyStructVariant0Variant0 {}

There was a similar issue #829 which was successfully fixed. This thing is a more advanced.

@ahl here you mention the ongoing work "to separate out schema processing such as merging schemas". Is that going to help?

Use serde(flatten) whenever possible

I would create a second issue out of that for the following. But let it be here for now. I put it here as it may be connected
The previous schema is actually created from the rust code with schemars:

#[derive(JsonSchema)]
struct MyStruct {
    #[serde(flatten)]
    pub first_enum: MyFirstEnum,
    #[serde(flatten)]
    pub second_enum: MySecondEnum,
}

#[derive(JsonSchema)]
#[serde(tag = "myfirsttag", rename_all = "snake_case")]
enum MyFirstEnum {
    A(String),
    B(u64)
}

#[derive(JsonSchema)]
#[serde(tag = "mysecondtag", rename_all = "snake_case")]
enum MySecondEnum {
    C(String),
    D(u64)
}

So after that, I would say "let's use serde(flatten) whenever it's possible". For this case, it sounds reasonable. Firstly, it deduplicates the code. Secondly, it helps with naming. Though I am not sure if it's reasonable for the general case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions