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

[5.0.0-rc] [generics]: add T: ToSchema bounds on impl instead of requiring it on definition? #1078

Closed
oxalica opened this issue Oct 3, 2024 · 1 comment · Fixed by #1079

Comments

@oxalica
Copy link
Contributor

oxalica commented Oct 3, 2024

I have generic types like this:

#[derive(utoipa::ToSchema)]
struct Signed<T> {
    payload: T,
    sig: String,
}

#[utoipa::path(post, path = "/api", request_body = Signed<String>)]
async fn post_message() {}

It fails to compile with:

error[E0277]: the trait bound `T: PartialSchema` is not satisfied
 --> src/main.rs:3:14
  |
3 |     payload: T,
  |              ^ the trait `ComposeSchema` is not implemented for `T`, which is required by `T: PartialSchema`
  |
  = note: required for `T` to implement `PartialSchema`
help: consider restricting type parameter `T`
  |
2 | struct Signed<T: utoipa::__dev::ComposeSchema> {
  |                ++++++++++++++++++++++++++++++

error[E0277]: the trait bound `T: ToSchema` is not satisfied
 --> src/main.rs:3:14
  |
3 |     payload: T,
  |              ^ the trait `ToSchema` is not implemented for `T`
  |
help: consider restricting type parameter `T`
  |
2 | struct Signed<T: utoipa::ToSchema> {
  |                ++++++++++++++++++

But the suggestion to define struct Signed<T: utoipa::ToSchema> would change the public API to require ToSchema for any Signed<T>. It would break other non-API-related code using Signed<T> on non-ToSchema types. My use case is to make utoipa dependency optional, so it's not possible to introduce breaking change on whether user enables utoipa feature.

I think a better solution would be generating the ToSchema bound on impl block, instead of requiring them on the struct definition. That is:

#[derive(ToSchema)]
struct Signed<T> { .. }
/// generates:
impl<T: ToSchema /*<- added by derive-macro*/> ToSchema for Signed<T> { .. }
@juhaku
Copy link
Owner

juhaku commented Oct 3, 2024

Good idea, thanks for taking this into action and submitting a patch 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Released
Development

Successfully merging a pull request may close this issue.

2 participants