define_derive_adhoc!() { /* proc-macro */ }
Expand description

Define a reuseable template

define_derive_adhoc! {
    [/// DOCS]
    [pub] MyMacro OPTIONS,.. =
    TEMPLATE
}

Then, MyMacro can be used with #[derive(Adhoc)] #[derive_adhoc(MyMacro)].

OPTIONS,.. is an optional comma-separated list of expansion options, which will be applied whenever this template is expanded.

DOCS, if supplied, are used as the rustdocs for the captured template macro derive_adhoc_template_MyMacro. derive-adhoc will then also append a note about how to invoke the template.

§Template definition macro derive_adhoc_template_MyMacro

The template is made into a macro_rules macro named derive_adhoc_template_MyMacro, which is referenced when the template is applied.

The template definition macro from define_derive_adhoc! must be in scope at the point where you try to use it (with #[derive(Adhoc)] #[derive_adhoc(MyMacro)]). See the documentation for #[derive(Adhoc)].

§Exporting a template for use by other crates

With pub MyMacro, define_derive_adhoc! exports the template for use by other crates. Then, it is referred to in other crates with #[derive_ahdoc(this_crate::MyMacro)].

I.e., pub MyMacro causes the derive_adhoc_template_MyMacro pattern macro to be exported with #[macro_export].

Note that a template is always exported at the crate top level, not in a sub-module, even if it is defined in a sub-module.

§You must re-export derive_adhoc; (usually no) semver implications

When exporting a template to other crates, you must also re-export derive_adhoc, at the top level of your crate:

#[doc(hidden)]
pub use derive_adhoc;

This is used to find the template expansion engine, and will arrange that your template is expanded by the right version of derive-adhoc. The template syntax is that for your version of derive-adhoc, even if the depending crate uses a different version of derive-adhoc.

You should not treat a breaking change to derive-adhoc’s template syntax (which is a major change to derive-adhoc), nor a requirement to use a newer template feature, as a breaking changes in the API of your crate. (You should use #[doc(hidden)], or other approaches, to discourage downstream crates from using the derive-adhoc version you re-export. Such use would be outside the semver guarantees.)

Changes that would require a semver bump for all libraries that export templates, will be rare, and specially marked in the derive-adhoc changelog.

§Namespacing within a template

Within the template, items within your crate can be referred to with $crate.

For other items, including from the standard library e.g., std::option::Option, you may rely on the context which uses the template to have a reasonable namespace, or use a explicit paths starting with std or core or $crate (perhaps naming a re-export).

Overall, the situation is similar to defining an exported macro_rules macro.