MaxCross
MaxCross

Reputation: 11

Conditional compilation based on proc_macro

Is it possible to somehow detect in a crate that it's used in proc_macro and include some items based on that?

Let's say I have a token_parser crate with a Token enum:

pub struct Group;
pub struct Ident;
pub struct Punct;
pub struct Literal;

pub enum Token {
    Group(Group),
    Ident(Ident),
    Punct(Punct),
    Literal(Literal)
}

It's intended to be a wrapper for a proc_macro::TokenTree, so I want to be able to use it inside a proc_macro crates. I don't want to manualy implement a converting logic in every crate, so I want something like this:

#[cfg(proc_macro)]
impl From<proc_macro::TokenTree> for Token {
    fn from(token: proc_macro::TokenTree) -> Self
    {
        todo!()
    }
}

while still having an option to use token_parser crate in normal crates.

P.S I'm aware of proc_macro2 crate. I will probably use it (or even syn) in the end, for now I'm just trying to understand how to do something like that myself properly.

Upvotes: 0

Views: 370

Answers (1)

Chip
Chip

Reputation: 28

There are primarily two ways I would reach for based on how I want to enable such functionality.

  1. feature for project-based enabling

If you want it only available when opted for, that's a fantastic case to use a cargo feature. Crates that want to use such functionality can then choose to enable this feature while other crates can choose to not enable the feature. Whether this feature should be default typically depends on how the library author believes it should/is used most of the time.

  1. cfg for platform-based enabling

As you may have seen from reading the proc_macro2 source, they conditionally enable a cfg in their build script1. On the wasm32 platform target it is disabled, otherwise it is enabled. This way is very useful in cases where enabling functionality mostly depends on the platform.

Upvotes: 1

Related Questions