A Cargo feature is a named option for making crate functionality optional. Enable it when a consumer needs that capability; otherwise the associated code can stay out of the project. This is useful when one library exposes several macros but users need only some of them. section 10.3 section 10.9
Declare feature names in Cargo.toml, then guard imports, modules, and public macro entry points with #[cfg(feature = "...")]. Keeping feature-specific generation in its own module lets one conditional module import hide the supporting implementation as well as the macro. section 10.3
Listing 10.12 lib.rs featuring a feature
// other imports, mod input, mod output
#[cfg(feature = "struct")] #1
use syn::DeriveInput;
#[cfg(feature = "struct")]
mod struct_output;
// find_yaml_values
// function-like macro
#[cfg(feature = "struct")] #2
#[proc_macro_attribute]
pub fn config_struct(attr: TokenStream, item: TokenStream)
-> TokenStream {
let input: ConfigInput = parse_macro_input!(attr);
let ast: DeriveInput = parse_macro_input!(item);
match find_yaml_values(&input) {
Ok(values) => struct_output::generate_annotation_struct( #3
ast, values, &input.exclude_from
).into(),
Err(e) => e.into_compile_error().into()
}
}
This listing gates the DeriveInput import, struct_output module, and config_struct attribute macro behind the same struct feature. section 10.3
A practical feature workflow is:
- Add a feature entry such as struct = [] in Cargo.toml. section 10.3
- Apply the same cfg condition to every import, module, and exported item required only by that feature. section 10.3
- Test without the feature: using its macro should fail as unknown while unaffected macros continue working. section 10.3
- Enable it at the dependency site with features = ["struct"] and verify the optional macro works again. section 10.3
- Consider a default feature when an otherwise empty public macro surface would be awkward; consumers can disable defaults when needed. section 10.3
Optional attribute macro
A config-macro crate can expose a function-like macro normally while placing config_struct behind struct. A consumer that writes use config_macro::config_struct; must request config-macro = { path = "../config-macro", features = ["struct"] }; otherwise config_struct is unavailable. section 10.3 section 10.3
Features also commonly activate optional dependencies and reexports. For example, a derive feature can activate a derive-macro dependency, while a macros feature can activate a separate procedural-macro crate. Feature flags can therefore control both visible APIs and the code required to implement them. section 10.6 section 10.6

