Generics don't work with `inline` and `flatten` when they have a default type or a trait bound
escritorio-gustavo opened this issue · 3 comments
As of #212, we can now properly inline a generic type, as long as the generic does not have trait bounds. We have added an ignored test to help future implementations.
Why did #212 not implement this?
#212 bases its decision of inlining the generic type based on wether or not the provided type returns "null"
from its .inline()
method. That basically means we are checking for the unit type ()
.
The problem is this doesn't work for trait bounds, since if you have any given trait, like ToString
it is unlikely that the unit type implements said trait, and since tuples are always foreign you cannot implement it yourself, since neither ToString
nor ()
are defined by your crate.
Solution
Somehow implement the trait bounds to the unit type? Honestly I have no idea, when I wrote this issue I had the crate's unit tests in mind, but now, from the perspective of generate_export_test
, all that matters is the unit type
Maybe we can accept some default_type
attribute that is a path to a struct defined in the user's crate that behaves the same as the unit type (inline
s to "null"
) and implements all necessary traits?
I'd love to find a solution to this. I think I get what's happening, but i'll have to really go through it all in detail to understand all the edge cases.
That being said, I feel like the workaround is alright for most usecases - IMHO, trait bounds on structs are barely ever neccessary (though people seem to often put them there). I had to google a bit to find good examples for when it's actually required (except Send
, Sync
or ?Sized
).
@NyxCode I managed to get this working!
The user will have to do the following:
#[derive(TS)]
struct Unit;
impl ToString for Unit {
fn to_string(&self) -> String {
"".to_owned()
}
}
#[derive(TS)]
#[ts(unit_type = "Unit")]
struct Generic<T: ToString> {
foo: T
}
Closed as discussed in #217