Derive Macro tor_hsservice::internal_prelude::Deftly
#[derive(Deftly)]
{
// Attributes available to this derive:
#[deftly]
#[derive_deftly]
#[derive_deftly_adhoc]
}
Expand description
Perform ad-hoc templating driven by a data structure
This macro does two things:
-
If
#[derive_deftly(MyMacro)]
attributes are also specified, they are taken to refer to reuseable templates defined withdefine_derive_deftly!
. Each suchMyMacro
is applied to the data structure.You can specify expansion options for each such template application, by writing
#[derive_deftly(MyMacro[OPTIONS,..])]
, where[OPTIONS,..]
is a comma-separated list of expansion options contained within[ ]
. -
If
#[derive_deftly_adhoc]
is specified, captures the data structure definition, so that it can be used with calls toderive_deftly_adhoc!
.
§#[deftly]
attribute
The contents of #[deftly]
attributes are made available
to templates via the
${Xmeta}
expansions.
If none of the template(s) recognise them,
it is an error,
(unless #[derive_deftly_adhoc]
is specified).
derive-deftly
does not impose any namespacing
within #[deftly]
:
§Captured data structure definition derive_deftly_driver_TYPE
The data structure is captured by defining
a macro_rules
macro called derive_deftly_driver_TYPE
,
where TYPE
is the name of the type
that #[derive(Deftly)]
is applied to.
§Scoping and ordering within the same crate
Summary of required ordering
define_derive_deftly! { MyMacro = ... }
#[derive(Deftly)] #[derive_deftly(MyMacro)] struct MyStruct { ... }
derive_deftly_adhoc! { MyStruct: ... }
Any reusable templates defined with
define_derive_deftly!
must lexically their precede
uses with #[derive(Deftly) #[derive_deftly(...)]
.
And, for one-off templates (derive_deftly_adhoc!
),
the data structure with its #[derive(Deftly)]
must lexically precede
the references in derive_deftly_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-deftly macro) from another crate
#[derive_deftly(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_deftly_template_MyMacro
:
use derive_deftly::{Deftly, derive_deftly_adhoc};
use other_crate::derive_deftly_template_TheirMacro;
#[derive(Deftly)]
#[derive_deftly(TheirMacro)]
struct MyStruct { // ...
§Exporting the driver for downstream crates’ templates
To cause the macro embodying the driver struct to be exported,
write:
#[derive_deftly_adhoc(pub)]
.
The driver can then be derived from in other crates,
with derive_deftly_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-deftly to a minor version,
as you may need to treat minor version updates in derive-deftly
as semver breaks for your crate.
And every time you update, you must read the CHANGELOG.md
,
since there is nothing that will warn you automatically
about breaking changes.