-
Notifications
You must be signed in to change notification settings - Fork 115
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
Infered types (_
) in #[ts(as = "...")]
#299
Conversation
Interesting! So |
I do think this is pretty neat, though I think it might be a bit unintuitive for anyone who doesn't know what If the syntax was |
Yes, this is mostly a way to resolve the discussion in #175 |
Both of these would require some heavy refactoring, because
We could make a fn parse_type(input: ParseStream) -> Result<Type> {
let str = parse_assign_str(input)?;
syn::parse_str(&str.replace("$type", "_"))
} but since this function wouldn't have access to the |
I think the understore is super intuitive, as it's already widely used throughout rust syntax. So the code is instantly readable. The other nice thing is that you could, for example, turn a type into a vector, such as |
There is also precedent for this behavior in
|
Oh, alright! Maybe it's just me then. |
macros/src/types/mod.rs
Outdated
@@ -46,3 +51,122 @@ fn type_def(attr: &StructAttr, ident: &Ident, fields: &Fields) -> Result<Derived | |||
Fields::Unit => unit::null(attr, &name), | |||
} | |||
} | |||
|
|||
pub(super) fn type_as_infer(type_as: &Type, original_type: &Type) -> Type { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is perfectly fine, but just an idea: Would changing the signature to type_as_infer(type_as: &Type, original: &mut Type) -> ()
make the impl cleaner? I think that might get rid of the parse_quote!
calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't mutate original_type
because deeper recursive calls into type_as_infer
require the original, unaltered type
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put something together in #305 to highlight what I had in mind. I've put the &mut
on the wrong argument in the snippet above, i think that caused some confusion. Sorry about that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've put something together in #305 to highlight what I had in mind.
Oh, that makes a lot more sense! I'll merge that in real quick
let ty = match field_attr.type_override { | ||
Some(type_override) => quote!(#type_override), | ||
None => { | ||
let ty = field_attr.type_as(&field.ty); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love how this got a lot simpler. Awesome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome stuff, great work!
Also, you were spot on with your take in #175. This solution keeps |
Interestingly, this kinda makes #[ts(as = "Option<_>", optional)]
field: Option<i32>, |
I just hope no one is crazy enough to do that 😆 |
Goal
This PR aims to allow the use of infered types (
_
) inside the#[ts(as = "...")]
attribute. The_
type will be interpreted as the field's original type. E.g.:is the same as:
but without having to repeat the original type.
This allows us to somewhat support using
#[ts(optional)]
with any type, by using#[ts(as = "Option<_>", optional)]
without requiring us to change the semantics of#[ts(optional)]
Changes
Added a recursive function to traverse the provided type and replace
Type::Infer(_)
with the field's original typeChecklist