define_derive_deftly_module

Macro define_derive_deftly_module 

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

Define a module with reuseable template definitions (beta)

define_derive_deftly_module! {
    [/// DOCS]
    [export] MyModule OPTIONS,..:
    [use SubModule; ..]
    TEMPLATE_DEFINITIONS
}

Then, use MyModule can be used in define_derive_deftly! (and, in another define_derive_deftly_module!).

TEMPLATE_DEFINITIONS may contain only ${define ..} and ${defcond }. (So it cannot define derives as-such, but it could contain the whole body of a derive as a ${define}.)

This feature is beta. It requires the beta cargo feature (but not any beta_deftly template option).

§Scope and (lack of) namespacing

All names defined in a module are accessible within any tamplate or module that uses the module (directly or indirectly).

So there is no namespacing: names are “global”. Like all ${define } and ${defcond }, scope is dynamic, not lexical.

Definitions in imported modules can be shadowed by subsequent definitions, including subsequent modules, and the importing template or module.

So definitions in general-purpose modules should usually have a namespace component within their name. This applies especially to “internal” definitions, which the module user is not intended to use or redefine.

§Documentation expansions in define_derive_deftly!

In define_derive_deftly!, DOCS can contain both literal #[doc] attributes, and template expansions that expand to #[doc] attributes. The template expansions can refer to ${define}s from imported modules. This allows re-use of documentation fragments.

The documentation for a module cannot contain expansions.

§Placement of use

In define_derive_deftly! use Module appears in the preamble, before the name of the template being defined. use statements in the body become part of the expansion, so will refer to Rust modules.

In define_derive_deftly_module!, use Module appears within the body, before the definitions. (This reflects the fact that the imported module becomes part of the module being defined, and that imported definitions cannot be used in the module’s documentation.)

§Options

The only OPTION supported is beta_deftly.

Beta features can be used in a module, if beta_deftly is specified in the module definition. A module which uses beta features can be imported by a template or module which does not itself specify beta_deftly.

use statements do not themselves require specifying beta_deftly; the cargo feature is sufficient.

§Module definition macro derive_deftly_module_MyModule

The module’s definitions are made into a macro_rules macro named derive_deftly_module_MyModule, which is referenced where the module is imported.

The module needs to be in Rust macro scope where it’s used. It does not need to be in scope for derive whose template uses it. (The module’s definitions are bodily incorporated into the importing template (or module) macro_rules macro.)e

§Semver implications of export:

Normally, template code present in different crates can be processed by different, perhaps semver-incompatible, versions of derive-deftly.

But, a whole derive must be processed by one version of derive-deftly. Ie, when you use a module from another crate, that other crate’s module’s template text gets processed with your version of derive-deftly.

Additionally, the lack of namespacing provides ample opportunity for unintended interactions and uncontrolled dependencies on internals.

There are no features in derive-deftly for helping make an exported module with a stable API, whatever that means.