Derive Macro derive_adhoc::Adhoc
source · #[derive(Adhoc)]
{
// Attributes available to this derive:
#[adhoc]
#[derive_adhoc]
}
Expand description
Perform ad-hoc templating driven by a data structure
This macro does two things:
-
It captures the data structure definition, so that it can be used with calls to
derive_adhoc!
. -
If
#[derive_adhoc(MyMacro)]
attributes are also specified, they are taken to refer to reuseable templates defined withdefine_derive_adhoc!
. Each suchMyMacro
is applied to the data structure.You can specify expansion options for each such template application, by writing
#[derive_adhoc(MyMacro[OPTIONS,..])]
, where[OPTIONS,..]
is a comma-separated list of expansion options contained within[ ]
.
§#[adhoc]
attribute
The contents of #[adhoc]
attributes are made available
to templates via the
${Xmeta}
expansions.
If the template(s) don’t use them, they are ignored.
derive-adhoc
does not impose any namespacing within #[adhoc]
:
all templates see the same adhoc meta attributes.
§Captured data structure definition derive_adhoc_driver_TYPE
The data structure is captured by defining
a macro_rules
macro called derive_adhoc_driver_TYPE
,
where TYPE
is the name of the type
that #[derive(Adhoc)]
is applied to.
§Scoping and ordering within the same crate
Summary of required ordering
define_derive_adhoc! { MyMacro = ... }
#[derive(Adhoc)] #[derive_adhoc(MyMacro)] struct MyStruct { ... }
derive_adhoc! { MyStruct: ... }
Any reusable templates defined with
define_derive_adhoc!
must lexically their precede
uses with #[derive(Adhoc) #[derive_adhoc(...)]
.
And, for one-off templates (derive_adhoc!
),
the data structure with its #[derive(Adhoc)]
must lexically precede
the references in derive_adhoc!
,
so that the data structure definition macro
is in scope.
In each case,
if the definition is in another module
in the same crate,
the defining module’s mod
statement must come before
the reference,
and
the mod
statement will need #[macro_use]
.
So the placement and order of mod
statements can matter.
§Applying a template (derive-adhoc macro) from another crate
#[derive_adhoc(some_crate::MyMacro)]
applies an exported (pub
) template
defined and exported by some_crate
.
You can import a template from another crate,
so you can apply it with an unqualified name,
with use
,
but the use
must refer to
the actual pattern macro name derive_adhoc_template_MyMacro
:
use other_crate::derive_adhoc_template_TheirMacro;
#[derive(Adhoc)]
#[derive_Adhoc(TheirMacro)]
struct MyStruct { // ...
§Exporting the driver for downstream crates’ templates
To cause the macro embodying the driver struct to be exported,
write:
#[derive_adhoc(pub)]
.
The driver can then be derived from in other crates,
with derive_adhoc! { exporting_crate::DriverStruct: ... }
.
This is a tricky feature, which should only be used by experts who fully understand the implications. It effectively turns the body of the struct into a macro, with a brittle API and very limited support for namespacing or hygiene.
See pub mod a_driver
in the example file pub-a.rs
,
in the source tree,
for a fuller discussion of the implications,
and some advice.
If you do this, you must pin your derive-adhoc to a minor version, as you may need to treat minor version updates in derive-adhoc as semver breaks for your crate.