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.