Derive Macro boulder::Generatable
source · [−]#[derive(Generatable)]
{
// Attributes available to this derive:
#[boulder]
}
Expand description
Derive the Generatable
trait for a type, creating a suitable
Generator
.
This is only implemented for structs with named fields; there is
no implementation for either enums or structs with unnamed fields.
All fields will be default constructed (i.e. Default::default()
)
in the absence of other instructions. You can customise the
construction process for your type by using the boulder
attribute as follows:
-
#[boulder(generator=Inc(0))]
Each successive instance produced by this generator should, by default, have a value one higher for this field than the previous one. The first generated value for this field should be 0.Inc(0)
can be replaced by an arbitrary expression which evaluates to aGenerator
. -
#[boulder(generatable)]
The type for this field implementsGeneratable
, so new instances of the containing type should have values for this field taken from the default sequence for the field type. -
#[boulder(generatable(a=Inc(3i32)))]
The type for this field implementsGeneratable
, and the generator for values for this field should be customised, such that the nested fielda
uses the generatorInc(3i32)
.Inc(3i32)
can be replaced by an arbitrary expression which evaluates to aGenerator
instance. -
#[boulder(sequence_generator=Repeat(2usize, 3usize))]
This field is assumed to be a collection type (a type which can be the target ofcollect()
). Successive instances should have alternately 2 and 3 items. The items will be default initialized. This tag stacks withgeneratable
,buildable
anddefault
to provide more control of the container contents.Repeat(2usize, 3usize)
can be replaced by an arbitrary expression which evaluates to aGenerator
.
The generator will additionally use all tags defined for
Buildable
if those specific to Generatable
are not present. In
this case, all instances in the sequence the generator produces
will receive the same value for the given field. This includes the
sequence
tag.
Example:
use boulder::{Generatable, Generator, Inc};
#[derive(Generatable)]
struct Foo {
// This field will be default initialized in every instance (a=0)
a: i32,
// This field will increase by 1 from 5 in successive instances.
#[boulder(generator=Inc(5))]
b: i32,
}
#[derive(Generatable)]
struct Bar {
// This field will take values from Foo::generator()
#[boulder(generatable)]
f1: Foo,
// This field will take values from Foo::generator().a(Inc(1)).build()
#[boulder(generatable(a=Inc(1)))]
f2: Foo,
// This field will be initialized with an increasing number of
// instances from Foo::generator().generate()
#[boulder(generatable, sequence_generator=Inc(0usize))]
f3: Vec<Foo>,
// This field will be initialized with one zero in every instance
#[boulder(sequence=1)]
ary: Vec<i32>,
}
let mut gen = Bar::generator();
let bar = gen.generate();
assert_eq!(bar.f1.a, 0);
assert_eq!(bar.f1.b, 5);
assert_eq!(bar.f2.a, 1);
assert_eq!(bar.f2.b, 5);
assert_eq!(bar.f3.len(), 0);
assert_eq!(bar.ary.len(), 1);
assert_eq!(bar.ary[0], 0);
let bar = gen.generate();
assert_eq!(bar.f1.a, 0);
assert_eq!(bar.f1.b, 6);
assert_eq!(bar.f2.a, 2);
assert_eq!(bar.f2.b, 6);
assert_eq!(bar.f3.len(), 1);
assert_eq!(bar.f3[0].a, 0);
assert_eq!(bar.f3[0].b, 5);
assert_eq!(bar.ary.len(), 1);
assert_eq!(bar.ary[0], 0);