cfg_attrs 2.0.0

An alternative to #[cfg_attr(...)] that is easier to use with doc comments.
Documentation

#[cfg_attrs { ... }]

Provides an alternative syntax to #[cfg_attr(...)] that is easier to use with doc comments.

Syntax
CfgAttrsAttribute :
  cfg_attrs CfgAttrs

CfgAttrs :
  ( { Attributes } ) | ConfiguredAttrs

ConfiguredAttrs :
  ( ConfigurationPredicate , Attributes )

Attributes :
  OuterAttribute* ( , OuterAttribute* )* ,?

Usage

#[cfg_attrs { ... }] should surround all other attributes on the item. A #[configure(<condition>, <attributes>)] helper attribute is provided within.

The syntax of that #[configure(...)] attribute is much like #[cfg_attr(...)], except the configured attributes use full attribute syntax. The advantage of this is that doc comments, which expand to #[doc = "..."] attributes, can be used in the #[configure(...)] syntax.

All of an item's doc comments should be placed within the #[cfg_attrs { ... }] attribute, even if they are not being configured. Additionally, the #[cfg_attrs { ... }] attribute should only appear once per item; #[configure(...)] can be used multiple times within it if you want multiple usages.

These restrictions are as a result of how proc-macro attributes work: they are expanded separately to other attributes, so their position among other attributes is lost. While you might put a #[cfg_attrs { ... }] attribute that configures doc comments between two non-configured doc comments, that isn't where it will be expanded to, so the documentation will be out of order.

Examples

#[cfg_attrs {
    /// This is an example struct.
    #[configure(
        debug_assertions,
        ///
        /// Hello! These are docs that only appear when
        /// debug assertions are active.
    )]
}]
struct Example;

This will expand to the following usage of #[cfg_attr(...)]:

/// This is an example struct.
#[cfg_attr(
    debug_assertions,
    doc = "",
    doc = " Hello! These are docs that only appear when",
    doc = " debug assertions are active."
)]
struct Example;

Which, if debug assertions are active, would be expanded to:

/// This is an example struct.
///
/// Hello! These are docs that only appear when
/// debug assertions are active.
struct Example;

#[cfg_attrs(...)] may also be used with attributes other than doc comments, though there is no real benefit to doing this:

#[cfg_attrs {
    #[configure(
        feature = "magic",
        #[sparkles]
        #[crackles]
    )]
}]
fn bewitched() {}

With that example being equivalent to:

#[cfg_attr(feature = "magic", sparkles, crackles)]
fn bewitched() {}