JelteF/derive_more

Exposing macros for reuse

Opened this issue · 4 comments

It'd be really handy to be able to reuse some of the derive_more macros, for example I'd like to be able to reuse the display-like formatting in my own macros so I can utilize them in something like this without reimplementing it from scratch (and also for consistency with e.g. #[derive(derive_more::Display)]):

#[derive(Error)]
struct SomeErr {
    #[error(label = "this should be greater than {target}")]
    span: Span,

    target: usize,
}

Is this something that's been considered?

What would you need to be exported that isn't exported now?

@JelteF not sure exactly, but I was wondering if you were open to the idea before I investigated more. I had a quick look and I think some (minor) refactoring would be required to export the string-formatting macros in a reusable fashion since at the moment they're essentially embedded with the actual trait generation, but it shouldn't be too hard to expose the reusable bits.

This is vague enough that it's hard to answer. Feel free to create a PR though with what you need, if it's a small change I'm definitely open to it.

@Porges I think the only things that could be further exposed by derive_more that might do what you want are the functions inside the proc_macro crate (if they exist at all) that do inner attribute parsing, and then that could be useful for other proc_macro crates that might want to do similar things. I don't know if derive_more has this kind of granularity in its implementation or if it intends to be a toolbox for other proc_macro crates (which could be interesting... like some trait extensions to syn types or whatever).

As for practical advice for anyone else arriving at this issue, I could recommend:

1 - For the particular example of deriving error, try thiserror;
2 - If you don't like writing proc_macro code, you can do a lot with derive_deftly, which feels like macro_rules! but is way more powerfull;
3 - If you're fine writing proc_macro crates and you're just finding parsing attributes to be annoying (like the #[error(label=...)] attribute in your example), you can try serde_tokenstream to help you parse them using structs that derive serde::Deserialize