GREsau / schemars

Generate JSON Schema documents from Rust code
https://graham.cool/schemars/
MIT License
797 stars 223 forks source link

Generating definition types for enums with serde tag #244

Open vron opened 1 year ago

vron commented 1 year ago

Hi,

First of all - thanks for a very usefull library. I'm using it for synchronizing types from rust for a large project.

However, one issue I have is that I would like to be able to refer to the structs that are parts of enums directly - but schemars seems to inline those struct (which I think is a bug?)

Consider the following input:

use schemars::{schema_for, JsonSchema};

#[derive(JsonSchema)]
pub struct MyStruct {
    pub my_int: i32,
    pub my_bool: bool,
    pub my_nullable_enum: Option<MyEnum>,
}

#[derive(JsonSchema)]
#[serde(tag = "type")]
pub enum MyEnum {
    StringNewType(String),
    StructVariant(SubType),
}

#[derive(JsonSchema)]
pub struct SubType {
    pub aa: i64,
}

fn main() {
    let schema = schema_for!(MyStruct);
    println!("{}", serde_json::to_string_pretty(&schema).unwrap());
}

Which generates:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "MyStruct",
  "type": "object",
  "required": [
    "my_bool",
    "my_int"
  ],
  "properties": {
    "my_bool": {
      "type": "boolean"
    },
    "my_int": {
      "type": "integer",
      "format": "int32"
    },
    "my_nullable_enum": {
      "anyOf": [
        {
          "$ref": "#/definitions/MyEnum"
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "definitions": {
    "MyEnum": {
      "oneOf": [
        {
          "type": [
            "object",
            "string"
          ],
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string",
              "enum": [
                "StringNewType"
              ]
            }
          }
        },
        {
          "type": "object",
          "required": [
            "aa",
            "type"
          ],
          "properties": {
            "aa": {
              "type": "integer",
              "format": "int64"
            },
            "type": {
              "type": "string",
              "enum": [
                "StructVariant"
              ]
            }
          }
        }
      ]
    }
  }
}

Note in particular that no definition is generated for SubType which means that I am unable to generate types that can be refered to in code generated from the schema.

vron commented 12 months ago

Hi,

Is there any interest in this? If I (with some pointers) tried to implement a PR for this - would it be likely to be accepted? @GREsau

vron commented 12 months ago

Closing - found #157 which this seems to be duplicate of - my question stands though if there would be interest in a PR to adress this?

vron commented 12 months ago

While debugging turns out this is actually not a duplicate! The other issue is about getting a ref for the enum type - this issue is about getting a ref to the struct inside the enum type.