utoipa icon indicating copy to clipboard operation
utoipa copied to clipboard

Derive Component doesn't support tuples?

Open kellpossible opened this issue 2 years ago • 4 comments

#[derive(Component)]
struct Bar {
    foo: (String, String)
}

or

#[derive(Component)]
struct Bar {
    foo: (String)
}

I get the following error message:

unexpected type in component part get type path, expected one of: Path, Reference, Group

kellpossible avatar Jun 17 '22 11:06 kellpossible

Yeah they are not supported. The reason is that there is no good way to serialize them as OpenAPI doc and the only way to represent tuples are to represent them as array of items with a specifc size. Also if tuple contains different types then we can only represent it as array of general object types thus not being helpful to the user. Here https://serde.rs/json.html tuples are serialized as array of types and OpenAPI cannot represent multitype arrays.

juhaku avatar Jun 17 '22 15:06 juhaku

The json schema generated for this struct is:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Bar",
  "type": "object",
  "required": [
    "foo"
  ],
  "properties": {
    "foo": {
      "type": "array",
      "items": [
        {
          "type": "string"
        },
        {
          "type": "string"
        }
      ],
      "maxItems": 2,
      "minItems": 2
    }
  }
}

I guess the subset of json schema that OpenAPI 3.0 uses doesn't include items...

Okay from the spec:

items - Value MUST be an object and not an array. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. items MUST be present if the type is array.

kellpossible avatar Jun 18 '22 01:06 kellpossible

Perhaps at least we could improve the error message?

kellpossible avatar Jun 18 '22 01:06 kellpossible

Yeah, we could, and also what we can do also is to implement support for this behaviour similary already existin for UnnamedStruct in https://github.com/juhaku/utoipa/blob/master/utoipa-gen/src/schema/component.rs#L323.

So what it does it creates an object array with the size of the array which will be the amount of tuple items. Adding this kind of behaviour to the component fields is not too big of a addition though. But I dont know whether it is useful for the users thus I haven't implemented it previously.

It's because Rust's type system is so flexible. So it makes it difficult to support all the type representations supported by the Rust in OpenAPI spec as it was not build for Rust originally.

juhaku avatar Jun 18 '22 11:06 juhaku

Related #330, #391

juhaku avatar Dec 07 '22 00:12 juhaku

Native support for tuples is coming here: #541

juhaku avatar Mar 23 '23 23:03 juhaku