1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
mod attributes;
mod builder;
mod generator;
mod repeat;
mod string;

use proc_macro::{self, TokenStream};

/// Derive the `Buildable` trait for a type, creating a suitable
/// `Builder`.
///
/// 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 is
///   `Foo`, where an arbitrary well-formed Rust expression can be
///   used in place of `Foo`.
///
/// - `#[boulder(buildable)]` The type for this field implements
///   `Buildable` itself, so new values should be constructed using
///   `T::builder().build()`.
///
/// - `#[boulder(buildable(a=5, b=10))]` The type for this field implements
///   `Buildable`, and new instances should be customised from the
///    default by setting `a=5` and `b=10` where `a` and `b` are
///    member names, and `5` and `10` 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 of
///   `collect()`). Generate 3 items and initialize a new collection
///   from them, where `3` can be replaced by an arbitrary well-formed
///   Rust expression. The generation mechanism will be taken from any
///   generator specification (`generator` or `generatable`) if one is
///   given; otherwise it will be from the builder specification
///   (`default` or `buildable`, as described above) if one is given;
///   otherwise the items will be default initialized.
///
/// Example:
/// ```rust
/// use boulder::{Buildable, Generatable, Builder};
///
/// #[derive(Buildable)]
/// struct Foo {
///   // This field will be default-initialized (a=0)
///   a: i32,
///   // This field will be initialized from the expression (b=5)
///   #[boulder(default=6-1)]
///   b: i32,
/// }
///
/// #[derive(Buildable)]
/// struct Bar {
///   // This field will be initialized as Foo::builder().build()
///   #[boulder(buildable)]
///   f1: Foo,
///   // This field will be initialized as Foo::builder().a(1).build()
///   #[boulder(buildable(a=1))]
///   f2: Foo,
///   // This field will be initialized with two copies of Foo::builder().build()
///   #[boulder(buildable, sequence=2)]
///   f3: Vec<Foo>,
///   // This field will be initialized with one zero
///   #[boulder(sequence=1)]
///   ary: Vec<i32>,
/// }
///
/// let foo = Foo::builder().build();
/// assert_eq!(foo.a, 0);
/// assert_eq!(foo.b, 5);
/// let bar = Bar::builder().build();
/// 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(), 2);
/// assert_eq!(bar.f3[0].a, 0);
/// assert_eq!(bar.f3[0].b, 5);
/// assert_eq!(bar.f3[1].a, 0);
/// assert_eq!(bar.f3[1].b, 5);
/// assert_eq!(bar.ary.len(), 1);
/// assert_eq!(bar.ary[0], 0);
/// ```
#[proc_macro_derive(Buildable, attributes(boulder))]
pub fn builder(input: TokenStream) -> TokenStream {
    builder::derive_buildable(syn::parse_macro_input!(input)).into()
}

/// 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 a `Generator`.
///
/// - `#[boulder(generatable)]` The type for this field implements
///   `Generatable`, 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
///   implements `Generatable`, and the generator for values for this
///   field should be customised, such that the nested field `a` uses
///   the generator `Inc(3i32)`. `Inc(3i32)` can be replaced by an
///   arbitrary expression which evaluates to a `Generator` instance.
///
/// - `#[boulder(sequence_generator=Repeat(2usize, 3usize))]` This
///   field is assumed to be a collection type (a type which can be
///   the target of `collect()`). Successive instances should have
///   alternately 2 and 3 items. The items will be default
///   initialized. This tag stacks with `generatable`, `buildable` and
///   `default` to provide more control of the container contents.
///   `Repeat(2usize, 3usize)` can be replaced by an arbitrary
///   expression which evaluates to a `Generator`.
///
/// 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:
/// ```rust
/// 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);
/// ```
#[proc_macro_derive(Generatable, attributes(boulder))]
pub fn generatable(input: TokenStream) -> TokenStream {
    generator::derive_generatable(syn::parse_macro_input!(input)).into()
}

/// Make a `Generator` for formatted Strings.
///
/// The arguments to this macro broadly match the `format!` macro. The
/// first argument is a format string, and then subsequent arguments
/// must resolve to instances of `Generator`, whose output will be
/// formatted and inserted into the string as usual.
///
/// This macro is particularly useful when deriving `Generatable`,
/// since it's quite awkward to construct the necessary lambdas inside
/// the arguments to the `boulder` attribute.
///
/// Example:
/// ```rust
/// use boulder::{Const, Generator, Inc, Pattern};
///
/// let mut g = Pattern!("hello-{}-{}", Inc(11i32), Const(4i32));
/// assert_eq!(g.generate(), "hello-11-4");
/// assert_eq!(g.generate(), "hello-12-4");
/// assert_eq!(g.generate(), "hello-13-4");
/// ```
#[proc_macro]
pub fn string_pattern(input: TokenStream) -> TokenStream {
    string::pattern_macro(syn::parse_macro_input!(input)).into()
}

/// Make a `Generator` that recycles a collection of values.
///
/// The main advantage of this macro, over using `Repeat` directly, is
/// that it will coerce the types of the arguments. This can make
/// declarations much (much) more succinct when strings are involved.
///
/// Example:
/// ```rust
/// use boulder::{Generatable, Generator, Repeat};
///
/// #[derive(Generatable)]
/// struct Foo {
///    #[boulder(generator=Repeat!("hi", "bye"))]
///    a: String
/// }
///
/// let mut g = Foo::generator();
/// assert_eq!(g.generate().a, "hi");
/// assert_eq!(g.generate().a, "bye");
/// ```
#[proc_macro]
pub fn repeat(input: TokenStream) -> TokenStream {
    repeat::repeat_macro(syn::parse_macro_input!(input)).into()
}

#[cfg(feature = "persian-rug")]
mod persian_rug;

#[cfg(feature = "persian-rug")]
/// 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 is
///   `Foo`, where an arbitrary well-formed Rust expression can be
///   used in place of `Foo`.
///
/// - `#[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 implements
///   `Buildable` itself, so new values should be constructed using
///   `T::builder().build()`.
///
/// - `#[boulder(buildable_with_persian_rug)]` The type for this field implements
///   `BuildableWithPersianRug` itself, so new values should be constructed using
///   `T::builder().build(context)`.
///
/// - `#[boulder(buildable(a=5, b=10))]` The type for this field implements
///   `Buildable`, and new instances should be customised from the
///    default by setting `a=5` and `b=10` where `a` and `b` are
///    member names, and `5` and `10` can be replaced by arbitrary
///    well-formed Rust expressions.
///
/// - `#[boulder(buildable_with_persian_rug(a=5, b=10))]` The type for
///   this field implements `BuildableWithPersianRug`, and new
///   instances should be customised from the default by setting `a=5`
///   and `b=10` where `a` and `b` are member names, and `5` and `10`
///   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 of
///   `collect()`). Generate 3 items and initialize a new collection
///   from them, where `3` can be replaced by an arbitrary well-formed
///   Rust expression. The generation mechanism will be taken from any
///   generator specification (`generator` or `generatable`) if one is
///   given; otherwise it will be from the builder specification
///   (`default` or `buildable`, 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 of `collect()`). Generate a number
///   of items dependent on the context, and initialize a new
///   collection from them, where `f(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` or
///   `generatable_with_persian_rug`) if one is given; otherwise it
///   will be from the builder specification (`default`, `buildable`,
///   `default_with_persian_rug` or `buildable_with_persian_rug` as
///   described above) if one is given; otherwise the items will be
///   default initialized.
///
/// Example:
/// ```rust
/// 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);
/// ```
#[proc_macro_derive(BuildableWithPersianRug, attributes(boulder))]
pub fn buildable_with_persian_rug(input: TokenStream) -> TokenStream {
    persian_rug::builder::derive_buildable_with_persian_rug(syn::parse_macro_input!(input)).into()
}

/// Derive the `GeneratableWithPersianRug` trait for a type, creating
/// a suitable `GeneratorWithPersianRug`.
///
/// 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 a `Generator`.
///
/// - `#[boulder(generator_with_persian_rug=Inc(0): Inc)]` The
///   expression must evaluate to a `GeneratorWithPersianRug`, and
///   must be followed by a type annotation. All of the built-in
///   `Generator` instances are also `GeneratorWithPersianRug`
///   instances for convenience, but this is most useful when you need
///   to use the contents of a `persian_rug::Context` as part of the
///   generation process.
///
/// - `#[boulder(generatable)]` The type for this field implements
///   `Generatable`, so new instances of the containing type should
///   have values for this field taken from the default sequence for
///   the field type.
///
/// - `#[boulder(generatable_with_persian_rug)]` The type for this
///   field implements `GeneratableWithPersianRug`, so new instances
///   of the containing type should have values for this field taken
///   from the default sequence for the field type. Note that this can
///   never take arguments.
///
/// - `#[boulder(generatable(a=Inc(3i32)))]` The type for this field
///   implements `Generatable`, and the generator for values for this
///   field should be customised, such that the nested field `a` uses
///   the generator `Inc(3i32)`. `Inc(3i32)` can be replaced by an
///   arbitrary expression which evaluates to a `Generator` instance.
///   Note that there is no equivalent form of
///   `generatable_with_persian_rug` with arguments due to the
///   difficulty of naming the resulting type in the current version
///   of Rust.
///
/// - `#[boulder(sequence_generator=Repeat(2usize, 3usize))]` This
///   field is assumed to be a collection type (a type which can be
///   the target of `collect()`). Successive instances should have
///   alternately 2 and 3 items. The items will be default
///   initialized. This tag stacks with `generatable`, `buildable` and
///   `default` to provide more control of the container contents.
///   `Repeat(2usize, 3usize)` can be replaced by an arbitrary
///   expression which evaluates to a `Generator`.
///
/// - `#[boulder(sequence_generator_with_persian_rug=Repeat(2usize,
///   3usize): Repeat)]` This field is assumed to be a collection type
///   (a type which can be the target of `collect()`). This behaves
///   similarly to `sequence_generator`, but now the expression must
///   be a `GeneratorWithPersianRug` and receives the context when it
///   is asked to produce each new collection size. The expression
///   must have a type annotation, so that the starting type for the
///   generator is known.
///
/// The generator will additionally use all tags defined for
/// `BuildableWithPersianRug` if those specific to
/// `GeneratableWithPersianRug` 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` and
/// `sequence_with_persian_rug` tags.
///
/// Example:
/// ```rust
/// use boulder::{GeneratableWithPersianRug, GeneratorWithPersianRug};
/// use persian_rug::{contextual, persian_rug, Context, Mutator, Proxy};
///
/// struct FooCounter;
///
/// impl GeneratorWithPersianRug<Rug> for FooCounter {
///    type Output = usize;
///    fn generate<'b, B>(&mut self, context: B) -> (usize, B)
///    where
///       B: 'b + Mutator<Context = Rug>
///    {
///       (context.get_iter::<Foo>().count(), context)
///    }
/// }
///
/// struct BarCounter;
///
/// impl GeneratorWithPersianRug<Rug> for BarCounter {
///    type Output = usize;
///    fn generate<'b, B>(&mut self, context: B) -> (usize, B)
///    where
///       B: 'b + Mutator<Context = Rug>
///    {
///       (context.get_iter::<Bar>().count(), context)
///    }
/// }
///
/// #[contextual(Rug)]
/// #[derive(GeneratableWithPersianRug)]
/// #[boulder(persian_rug(context=Rug))]
/// struct Foo {
///   // This field will be default initialized in every instance (a=0)
///   a: i32,
///   // This field will be the number of Foo instances in existence when this instance was made.
///   #[boulder(generator_with_persian_rug=FooCounter: FooCounter)]
///   b: usize,
/// }
///
/// #[contextual(Rug)]
/// #[derive(GeneratableWithPersianRug)]
/// #[boulder(persian_rug(context=Rug))]
/// struct Bar {
///   // This field will take values from Foo::generator()
///   #[boulder(generatable_with_persian_rug)]
///   f1: Proxy<Foo>,
///   // This field will be initialized with an instance of Foo for every
///   // existing instance of Bar.
///   #[boulder(generatable_with_persian_rug, sequence_generator_with_persian_rug=BarCounter: BarCounter)]
///   f2: Vec<Proxy<Foo>>,
/// }
///
/// #[persian_rug]
/// struct Rug(#[table] Foo, #[table] Bar);
///
/// let mut r = Rug(Default::default(), Default::default());
/// let mut gen = Proxy::<Bar>::generator();
/// let (bar, _) = gen.generate(&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(&bar).f2.len(), 0);
/// let (bar, _) = gen.generate(&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(&bar).f2.len(), 1);
/// assert_eq!(r.get(&r.get(&bar).f2[0]).a, 0);
/// assert_eq!(r.get(&r.get(&bar).f2[0]).b, 2);
/// ```
#[cfg(feature = "persian-rug")]
#[proc_macro_derive(GeneratableWithPersianRug, attributes(boulder))]
pub fn generatable_with_persian_rug(input: TokenStream) -> TokenStream {
    persian_rug::generator::derive_generatable_with_persian_rug(syn::parse_macro_input!(input))
        .into()
}