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

Replacement for split_for_impl() on Generics? #26

Closed
MTRNord opened this issue Jun 18, 2022 · 3 comments
Closed

Replacement for split_for_impl() on Generics? #26

MTRNord opened this issue Jun 18, 2022 · 3 comments

Comments

@MTRNord
Copy link

MTRNord commented Jun 18, 2022

Syn offers https://docs.rs/syn/latest/syn/struct.Generics.html#method.split_for_impl for their generics to easily add implementations. I couldn't find an obvious way how to do this with venial. Is there a way, and if so, what would be the correct way?

@MTRNord
Copy link
Author

MTRNord commented Jun 18, 2022

My best guess was this, however I am not sure if "as_inline_args" i actually the one I want here:

    let impl_generics = input.generic_params.unwrap().as_inline_args();
    let ty_generics = input.generic_params.unwrap().params.iter().filter_map(|(param, _)| {
        if param.is_ty() {
            Some(param.name)
        } else {
            None
        }
    });

Especially as InlineGenericArgs is not usable via the public interface as the module it is in seems to be private.

@PoignardAzur
Copy link
Owner

Especially as InlineGenericArgs is not usable via the public interface as the module it is in seems to be private.

Right, InlineGenericArgs should probably be exported. That's an oversight.

It doesn't matter too much, since you can't build the type directly anyway and the builder function is public.

Is there a way, and if so, what would be the correct way?

Given the syn use-case:

let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
quote! {
    impl #impl_generics MyTrait for #name #ty_generics #where_clause {
        // ...
    }
}

Venial doesn't have an "all-in-one" method.

Instead you'd have:

let impl_generics = input.generic_params().unwrap();
let ty_generics = input.generic_params().unwrap().as_inline_args();

Though the idiomatic solution would be to match the declaration on its type (struct, enum or union) before trying to manipulate its generic arguments:

let struct_input = input.as_struct().unwrap();
let impl_generics = struct_input.generic_params.unwrap();
let ty_generics = struct_input.generic_params.unwrap().as_inline_args();
let where_clause = struct_input.where_clause;

I haven't really documented that idiom, though.

@PoignardAzur
Copy link
Owner

Added documentation in #48. I'm closing this in the meantime.

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

No branches or pull requests

2 participants