Derive Macro boulder::BuildableWithPersianRug
source · [−]#[derive(BuildableWithPersianRug)]
{
// Attributes available to this derive:
#[boulder]
}
persian-rug
only.Expand description
Derive the BuildableWithPersianRug
trait for a type, creating a
suitable BuilderWithPersianRug
.
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 in the absence of other
instructions. You can customise the construction process for your
type by using the boulder
attribute on its fields, as follows:
-
#[boulder(default=Foo)]
The default value for this field isFoo
, where an arbitrary well-formed Rust expression can be used in place ofFoo
. -
#[boulder(default_with_persian_rug=|context| {(Foo, context)})]
The default value for this field is derived from the context alone, via a lambda or function which receives the context, and must return it. -
#[boulder(buildable)]
The type for this field implementsBuildable
itself, so new values should be constructed usingT::builder().build()
. -
#[boulder(buildable_with_persian_rug)]
The type for this field implementsBuildableWithPersianRug
itself, so new values should be constructed usingT::builder().build(context)
. -
#[boulder(buildable(a=5, b=10))]
The type for this field implementsBuildable
, and new instances should be customised from the default by settinga=5
andb=10
wherea
andb
are member names, and5
and10
can be replaced by arbitrary well-formed Rust expressions. -
#[boulder(buildable_with_persian_rug(a=5, b=10))]
The type for this field implementsBuildableWithPersianRug
, and new instances should be customised from the default by settinga=5
andb=10
wherea
andb
are member names, and5
and10
can be replaced by arbitrary well-formed Rust expressions. -
#[boulder(sequence=3)]
This field is assumed to be a collection type (a type which can be the target ofcollect()
). Generate 3 items and initialize a new collection from them, where3
can be replaced by an arbitrary well-formed Rust expression. The generation mechanism will be taken from any generator specification (generator
orgeneratable
) if one is given; otherwise it will be from the builder specification (default
orbuildable
, as described above) if one is given; otherwise the items will be default initialized. -
#[boulder(sequence_with_persian_rug=|context| {(f(context), context)}]
This field is assumed to be a collection type (a type which can be the target ofcollect()
). Generate a number of items dependent on the context, and initialize a new collection from them, wheref(context)
can be replaced by an arbitrary well-formed Rust expression. The generation mechanism will be taken from any generator specification (generator
,generatable
,generator_with_persian_rug
orgeneratable_with_persian_rug
) if one is given; otherwise it will be from the builder specification (default
,buildable
,default_with_persian_rug
orbuildable_with_persian_rug
as described above) if one is given; otherwise the items will be default initialized.
Example:
use boulder::{BuildableWithPersianRug, GeneratableWithPersianRug, BuilderWithPersianRug};
use persian_rug::{contextual, persian_rug, Context, Proxy};
#[contextual(Rug)]
#[derive(BuildableWithPersianRug)]
#[boulder(persian_rug(context=Rug))]
struct Foo {
// This field will be default-initialized (a=0)
a: i32,
// This field will be initialized from the number of Bars currently in the context
#[boulder(default_with_persian_rug=|context| (context.get_iter::<Bar>().count().try_into().unwrap(), context))]
b: i32,
}
#[contextual(Rug)]
#[derive(BuildableWithPersianRug)]
#[boulder(persian_rug(context=Rug))]
struct Bar {
// This field will be initialized as Foo::builder().build()
#[boulder(buildable_with_persian_rug)]
f1: Proxy<Foo>,
// This field will be initialized as Foo::builder().a(1).build()
#[boulder(buildable_with_persian_rug(a=1))]
f2: Proxy<Foo>,
// This field will be initialized with as many items as there are
// pre-existing Foos of Foo::builder().build()
#[boulder(buildable_with_persian_rug, sequence_with_persian_rug=|context| (context.get_proxy_iter::<Foo>().count(), context))]
f3: Vec<Proxy<Foo>>,
}
#[persian_rug]
struct Rug(#[table] Foo, #[table] Bar);
let mut r = Rug(Default::default(), Default::default());
let (foo, _) = Proxy::<Foo>::builder().build(&mut r);
assert_eq!(r.get(&foo).a, 0);
assert_eq!(r.get(&foo).b, 0);
let (bar, _) = Proxy::<Bar>::builder().build(&mut r);
assert_eq!(r.get(&r.get(&bar).f1).a, 0);
assert_eq!(r.get(&r.get(&bar).f1).b, 0);
assert_eq!(r.get(&r.get(&bar).f2).a, 1);
assert_eq!(r.get(&r.get(&bar).f2).b, 0);
assert_eq!(r.get(&bar).f3.len(), 3);
assert_eq!(r.get(&r.get(&bar).f3[0]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[0]).b, 0);
assert_eq!(r.get(&r.get(&bar).f3[1]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[1]).b, 0);
assert_eq!(r.get(&r.get(&bar).f3[2]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[2]).b, 0);
let (foo, _) = Proxy::<Foo>::builder().build(&mut r);
assert_eq!(r.get(&foo).a, 0);
assert_eq!(r.get(&foo).b, 1);
let (bar, _) = Proxy::<Bar>::builder().build(&mut r);
assert_eq!(r.get(&r.get(&bar).f1).a, 0);
assert_eq!(r.get(&r.get(&bar).f1).b, 1);
assert_eq!(r.get(&r.get(&bar).f2).a, 1);
assert_eq!(r.get(&r.get(&bar).f2).b, 1);
assert_eq!(r.get(&bar).f3.len(), 9);
assert_eq!(r.get(&r.get(&bar).f3[0]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[0]).b, 1);
assert_eq!(r.get(&r.get(&bar).f3[1]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[1]).b, 1);
assert_eq!(r.get(&r.get(&bar).f3[2]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[2]).b, 1);
assert_eq!(r.get(&r.get(&bar).f3[8]).a, 0);
assert_eq!(r.get(&r.get(&bar).f3[8]).b, 1);