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

Define a reuseable template

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

Then, MyMacro can be used with #[derive(Deftly)] #[derive_deftly(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_deftly_template_MyMacro. derive-deftly will then also append a note about how to invoke the template.

§Template definition macro derive_deftly_template_MyMacro

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

The template definition macro from define_derive_deftly! must be in scope at the point where you try to use it (with #[derive(Deftly)] #[derive_deftly(MyMacro)]). If the template definition is in another module, you may need to annotate that module with #[macro_use]. See the documentation for #[derive(Deftly)].

§Exporting a template for use by other crates

With pub MyMacro, define_derive_deftly! 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_deftly_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. Also, note that pub does not have any effect on visibility of the template within the same crate. You may still need #[macro_use].

§You must re-export derive_deftly; semver implications

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

#[doc(hidden)]
pub use derive_deftly;

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

You should not treat a breaking change to derive-deftly’s template syntax (which is a major change to derive-deftly), 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-deftly version you re-export. Such use would be outside the semver guarantees.)

You should call derive_deftly::pub_template_semver_check! once in each crate that exports macros. This will notify you, by breaking your build, if you update to a derive-deftly version that has semver implications for other crates that use your macros.

Changes that would require a semver bump for all libraries that export templates, will be rare, and specially marked in the derive-deftly changelog. Search for sections with titles containing “pub template semver”.

§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.