GREsau/schemars

default member missing in schema for generic type that implements Default

seem-less opened this issue · 2 comments

Hi there,

I would expect that the generated schema includes information as to which enum value is the default here

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(
    bound(
        serialize = "A: Default + Serialize",
        deserialize = "A: Default + Deserialize<'de>"
    )
)]
#[schemars(bound = "A: Default + JsonSchema")]
struct SomeStruct<A = Animals> {
	#[serde(default)]
    things: A,
    number: u32,
}

#[derive(Default, Debug, Serialize, Deserialize, JsonSchema)]
enum Animals {
    #[default]
    Cow,
    Tiger,
    Giraffe,
}

#[derive(Default, Debug, Serialize, Deserialize, JsonSchema)]
enum Cars {
    #[default]
    Honda,
    Toyota,
    Mitsubishi,
}

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

which generates:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "SomeStruct_for_Animals",
  "type": "object",
  "required": [
    "number"
  ],
  "properties": {
    "number": {
      "type": "integer",
      "format": "uint32",
      "minimum": 0.0
    },
    "things": {
      "$ref": "#/definitions/Animals"
    }
  },
  "definitions": {
    "Animals": {
      "type": "string",
      "enum": [
        "Cow",
        "Tiger",
        "Giraffe"
      ]
    }
  }
}

If I change the struct to:

#[derive(Debug, Serialize, Deserialize, JsonSchema)]
struct SomeStruct {
    #[serde(default)]
    things: Animals,
    number: u32,
}

the generated output is:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "SomeStruct",
  "type": "object",
  "required": [
    "number"
  ],
  "properties": {
    "number": {
      "type": "integer",
      "format": "uint32",
      "minimum": 0.0
    },
    "things": {
      "default": "Cow",
      "allOf": [
        {
          "$ref": "#/definitions/Animals"
        }
      ]
    }
  },
  "definitions": {
    "Animals": {
      "type": "string",
      "enum": [
        "Cow",
        "Tiger",
        "Giraffe"
      ]
    }
  }
}

How can I ensure that the default enum is included in the generated schema?

GREsau commented

This is because the JsonSchema derive doesn't know whether A implements Serialize - you can fix it by adding an extra Serialize bound like this:

#[schemars(bound = "A: Default + JsonSchema + Serialize")]
struct SomeStruct<A = Animals> {
    #[serde(default)]
    things: A,
    number: u32,
}

awesome thanks!