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

Refactor alises support on ToSchema derive #546

Merged
merged 3 commits into from
Mar 28, 2023
Merged

Refactor alises support on ToSchema derive #546

merged 3 commits into from
Mar 28, 2023

Conversation

juhaku
Copy link
Owner

@juhaku juhaku commented Mar 27, 2023

Prior to this commit the implementation was not able to resolve nested generics within aliases. That lead scenarios where types with extensive use of lifetimes was not possible.

This commit takes another approach on aliases support for ToSchema derive macro that provides generic schema types. Instead of trying to parse Generics manually we parse syn::Type instead that contains generics as is allowing complex generic arguments with lifetimes to be used.

Fundamental difference is that we create TypeTree for alias and the implementor type. Then we compare generic arguments to the field arguments and replace matching occurrences.

 #[derive(ToSchema)]
 #[aliases(Paginated1 = Paginated<'b, String>, Paginated2 = Paginated<'b, Cow<'b, bool>>)]
 struct Paginated<'r, T> {
     pub total: usize,
     pub data: Vec<T>,
     pub next: Option<&'r str>,
     pub prev: Option<&'r str>,
 }

One caveat with this approach is that the lifetimes now need to be also defined on the left side of the equals (=) mark.

Removed the need to define lifetimes on left side of the equals (=) sign.

Fixes #427, Fixes #524

Prior to this commit the implementation was not able to resolve
nested generics within aliases. That lead scenarios where types with
extensive use of lifetimes was not possible.

This commit takes another approach on aliases support for `ToSchema`
derive macro that provides generic schema types. Instead of trying to
parse `Generics` manually we parse `syn::Type` instead that contains
generics as is allowing complex generic arguments with lifetimes to be
used.

Fundamental difference is that we create `TypeTree` for alias and the
implementor type. Then we compare generic arguments to the field
arguments and replace matching occurrences.
```rust
 #[derive(ToSchema)]
 #[aliases(Paginated1<'b> = Paginated<'b, String>, Paginated2<'b> = Paginated<'b, Cow<'b, bool>>)]
 struct Paginated<'r, T> {
     pub total: usize,
     pub data: Vec<T>,
     pub next: Option<&'r str>,
     pub prev: Option<&'r str>,
 }
```

One caveat with this approach is that the lifetimes now need to be also
defined on the left side of the equals (=) mark.
juhaku added 2 commits March 28, 2023 03:32
Remove need to define lifetimes on left side of equals (=) sign.
```rust
 #[aliases(Paginated1 = Paginated<'b, String>, Paginated2 = Paginated<'b, Cow<'b, bool>>)]
```
@juhaku juhaku merged commit 1d26a65 into master Mar 28, 2023
@juhaku juhaku deleted the rework-aliases branch March 28, 2023 20:02
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 this pull request may close these issues.

Nested generics Generics do not work with lifetime specifiers
1 participant