Making Constructor set fields with Default
Sometimes, we'd like to make a template template
that behave in different ways for different fields.
For example, let's suppose that we want our Constructor
template
to be able to set fields to their default values,
and not take them as arguments.
We can do this with an explicit conditional for each field:
Here we're using a new construct:
$when
.
It's only valid inside a loop like $( ... )
or ${for ...}
.
It causes the expansion of the loop body to be suppressed
whenever the condition is not true.
The condition in this cases is not(fmeta(constructor(default)))
.
(See // (1)
.)
You've seen fmeta
before;
it's true when a given attribute is present on the current field.
The not
condition
is just how we express negation.
All together, this $when
keyword causes each field
that has #[deftly(Constructor(default))]
applied to it
to be omitted from the list of arguments
to the new()
function.
Note at
// (2)
that we're using::std::default::Default::default()
, rather than callingDefault::default()
unconditionally. Remember, macros expand at the position where they are invoked, and it's possible that we'll be invoked in a module that has been built without the standard prelude.
Besides $not
,
you can use other boolean operators in conditions too:
there is an
any(...)
that is true
whenever at least one of its arguments is true,
and an
all(...)
that is true
when all of its arguments are true.