Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

derive ToSchema fails for types using generics #574

Closed
jayvdb opened this issue Apr 13, 2023 · 6 comments · Fixed by #1034
Closed

derive ToSchema fails for types using generics #574

jayvdb opened this issue Apr 13, 2023 · 6 comments · Fixed by #1034
Labels
Generics - Hard Stuff concerning generics implementation

Comments

@jayvdb
Copy link
Contributor

jayvdb commented Apr 13, 2023

Using #[derive(ToSchema)] on types like geo_types::Coord fails because it uses generics

e.g. jayvdb/geo@9b2c876

pub struct Coord<T: CoordNum = f64> {
    pub x: T,
    pub y: T,
}

becomes

      "Coord": {
        "type": "object",
        "required": [
          "x",
          "y"
        ],
        "properties": {
          "x": {
            "$ref": "#/components/schemas/T"
          },
          "y": {
            "$ref": "#/components/schemas/T"
          }
        }
      },

The basic fix for this would be to recognise the T: CoordNum = f64, and use f64 for each T, and also fail if the struct was designed using T: CoordNum without any default type for T, as in that case utoipa has a lot more work to do in order to know what CoordNum might be.

@juhaku
Copy link
Owner

juhaku commented Apr 14, 2023

Oh, the scenario with generics having = DefaultType have not been implemented. Support for this perhaps could be implemented, but that would only make it support the DefaultType and when used with some else the generated schema does not match to the actual schema. That's why with generics there is a need to use #[aliases(...)] but in the case of geotypes I am not convinced that it actually would work. utoipa needs to know possible types upon type creation and not when it is used with.

Perhaps the manual implementation is better, but there is the overhead of double declaring the properties. I posted a example of manual implementation with PartialSchema to here #566 (reply in thread).

@johnperry-math
Copy link

@jayvdb I had an issue like this, only it involved core::ops::range::RangeInclusive. My solution was to create a new struct for the sake of annotating it and assign a value_type. Something like this for your case:

#[allow(dead_code)]
#[derive(ToSchema)]
pub struct Coord64 {
   pub x: f64,
   pub y: f64,
}

#[derive(Serialize, Deserialize, ToSchema)]
pub struct Client {
   #[schema(value_type=Coord64)]
   field: Coord<f64>,
   // ...
}

@juhaku
Copy link
Owner

juhaku commented Apr 15, 2023

Apart from that there are few alternatives one might consider when creating ToSchema implementation for type of external crate #507 (comment).

@jayvdb
Copy link
Contributor Author

jayvdb commented Apr 17, 2023

Created #588 showing some of the limitations and workarounds for generics.

@jayvdb
Copy link
Contributor Author

jayvdb commented Apr 21, 2023

My colleague @joaommartins did some work on improving ToSchema to handle generics, before we started using schema_with, and unfortunately before f7dfff8 so the commits are not easily rebased. That said, if anyone is interested in pursuing this, they may be instructive to some degree. The commits are at franklin-ai@d135fec and franklin-ai@fa3586f

@juhaku juhaku added the Generics - Hard Stuff concerning generics implementation label Sep 4, 2024
@juhaku
Copy link
Owner

juhaku commented Sep 10, 2024

There is now new implementation for generics coming up in #1034 which should solve the issue with aliases approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Generics - Hard Stuff concerning generics implementation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants