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
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
/*!

This crate provides general mechanisms for implementing traits on types by
forwarding an implementation provided by another type.

Two different forwarding methods are provided: Forwarding traits implemented by
members, and forwarding traits implemented by types that the receiver type can
convert to.  These methods may be used in combination on the same receiver type.
This crate fully supports generic traits and struct types.

For more details about capabilities and limitations, see the documentation pages
for the individual macros.

# Basics

In order to forward a trait, some basic things are needed.

```rust
use forward_traits::{forwardable, forward_receiver, forward_traits_via_member};
```

We need a trait definition which is annotated with information which is used to
generate forwarded implementations.  This is done by applying the
`#[forwardable]` attribute to the definition.

```rust
# use forward_traits::forwardable;
#[forwardable]
trait FooTrait
{
	type Bar;

	fn foo (&self) -> &Self::Bar;

	const BAZ: u32;
}
```

Then we need a type which initially implements this trait.

```rust
# trait FooTrait { type Bar; fn foo (&self) -> &Self::Bar; const BAZ: u32; }
struct A {}

impl FooTrait for A
{
	type Bar = Self;

	fn foo (&self) -> &Self::Bar { self }

	const BAZ: u32 = 42;
}
```

Next, we need a type for which we want to implement this trait by forwarding the
implementation found on the initially implementing type.  There are a few
different ways to define such a type, but here we will demonstrate the newtype
idiom.  This type needs to be annotated with the `#[forward_receiver]`
attribute.

```rust
# use forward_traits::forward_receiver;
# struct A {}
#[forward_receiver]
struct B (A);
```

Lastly, we need to specify that we want to forward a trait using one of the
forwarding macros. In this case, we want to forward a trait implemented by a
member, so we write:

```rust
# use forward_traits::{forwardable, forward_receiver, forward_traits_via_member};
# #[forwardable]
# trait FooTrait { type Bar; fn foo (&self) -> &Self::Bar; const BAZ: u32; }
# struct A {}
# impl FooTrait for A { type Bar = Self; fn foo (&self) -> &Self::Bar { self } const BAZ: u32 = 42; }
# #[forward_receiver]
# struct B (A);
forward_traits_via_member! (B . 0, FooTrait);
```

And now we can see that the trait is properly forwarded.

```rust
# use forward_traits::{forwardable, forward_receiver, forward_traits_via_member};
# #[forwardable]
# trait FooTrait { type Bar; fn foo (&self) -> &Self::Bar; const BAZ: u32; }
# struct A {}
# impl FooTrait for A { type Bar = Self; fn foo (&self) -> &Self::Bar { self } const BAZ: u32 = 42; }
# #[forward_receiver]
# struct B (A);
# forward_traits_via_member! (B . 0, FooTrait);
assert_eq! (<B as FooTrait>::BAZ, 42);
```

# Re-Exporting Forwardable Traits

When re-exporting forwardable traits, the `#[forwardable]` attribute should be
applied to the use statement as well.  Note that the attribute will interpret
every item in the use tree as a trait that should be forwardable.  If you want
to re-export items that aren't forwardable traits from the same module(s),
you'll need to separate those re-exports out into another use statement;

```rust
use forward_traits::forwardable;

mod inner
{
	use forward_traits::forwardable;

	#[forwardable]
	pub trait Foo {}

	pub struct Bar {}
}

#[forwardable]
pub use inner::Foo;

pub use inner::Bar;
```

# Traits in Other Crates

Forwarding traits works with traits in other crates, so long as those trait
definitions are annotated with `#[forwardable]`.

If not, then annotations must be supplied separately.  When supplying
annotations in this way, the trait is imported (or re-exported if a visibility
modifier is supplied) at the location of the annotation macro.  When forwarding
this trait, you must refer to this import/re-export (or a re-export thereof).

```rust
use forward_traits
::{
	supply_forwarding_info_for_trait,
	forward_receiver,
	forward_traits_via_member
};

// This has the side-effect of importing IntoIterator into the current scope.
supply_forwarding_info_for_trait!
(
	std::iter::IntoIterator,
	trait
	{
		type Item;
		type IntoIter;
		fn into_iter (self) -> Self::IntoIter;
	}
);

#[forward_receiver]
struct VecWrapper <T> (Vec <T>);

// Note that we are referring to the IntoIterator in the current scope.
forward_traits_via_member! (VecWrapper . 0, IntoIterator);

// Now we can call the trait method on the wrapper type.
VecWrapper (vec! (1, 2, 3)) . into_iter ();
```

*/

mod generics;

mod partial_eval;
mod mangle;

mod uncurry;

mod transform_use;

mod type_def_info;
mod trait_def_info;
mod forwarded_trait_info;

mod member;

mod transformer;
mod conversion_transformer;
mod member_transformer;

mod forwardable;
mod supply_trait_info;
mod forward_receiver;

mod forward_via_conversion;
mod forward_via_member;

use proc_macro::TokenStream;

/**

This attribute primarily annotates trait definitions with forwarding
information. Secondarily, it is also used to make sure that the forwarding info
is properly re-exported along with the traits that it belongs to.

# Mechanism

The way that this attribute works is by defining a macro which can be used to
uncurry the trait forwarding information into another macro.

Due to limitations of macro export rules, a mangled version of that macro's name
is also created and exported into the crate root.  While these names are mangled
so that they're unlikely to cause name collisions, annotating trait definitions
of the same name in two different modules of the same crate will _definitely_
cause a problem.  Please keep trait names within a single crate unique.

# Annotating Trait Definitions

Use on trait definitions is pretty simple.  Just apply the attribute.

```rust
# use forward_traits::forwardable;
#[forwardable]
trait Foo
{
	// ...
}
```

The only consideration is that any types used for method arguments or associated
constants should be named by their fully-qualified paths.  This will prevent
name-resolution errors from occurring in the macro-generated implementations.

# Annotating Re-Exports

When re-exporting a trait that has been annotated, the use statement that does
the re-export should also be annotated.

```rust
# use forward_traits::forwardable;
mod foo
{
	# use forward_traits::forwardable;
	#[forwardable]
	pub trait Foo
	{
		// ...
	}
}

#[forwardable]
pub use foo::Foo;
```

The forwarding information is located by modifying the path of the trait passed
into the forwarding macro.  If the forwarding information isn't re-exported
alongside the trait, it won't be properly located if a path to the un-annotated
re-export is used in the forwarding macro.

*/
#[proc_macro_attribute]
pub fn forwardable (attr: TokenStream, item: TokenStream) -> TokenStream
{
	forwardable::forwardable_impl (attr, item)
}

/**

This attribute annotates type definitions with forwarding information.

# Mechanism

The way that this attribute works is by defining a macro which can be used to
uncurry the type information into another macro.

Due to limitations of macro export rules, a mangled version of that macro's name
is also created and exported into the crate root.  While these names are mangled
so that they're unlikely to cause name collisions, annotating type definitions
of the same name in two different modules of the same crate will _definitely_
cause a problem.  Please keep type names within a single crate unique.

# Usage

Usage of this attribute is pretty simple.  Just apply it to type definitions.

```rust
# use forward_traits::forward_receiver;
#[forward_receiver]
struct Foo
{
	// ...
}
```

Both regular structs and tuple-structs are supported.

# Limitations

The only types that are supported are structs.  Forwarding methods for enums can
be done in some circumstances easily enough, but figuring out what type to use
as the base for the associated types and constants is not as straightforward.
Solving those sorts of problems is beyond the scope of this crate.

```rust,compile_fail
# use forward_traits::forward_receiver;
// Error: expected `struct`
#[forward_receiver]
enum Foo
{
	// ...
}
```

*/
#[proc_macro_attribute]
pub fn forward_receiver (attr: TokenStream, item: TokenStream) -> TokenStream
{
	forward_receiver::forward_receiver_impl (attr, item)
}

/**

This macro allows the user to supply forwarding information for a trait in an
external crate that they do not control.

# Usage

The macro takes two arguments.  The first is a path to the trait that we're
providing annotations for.  The second is the annotation information.

The annotation information is basically just a subset of the parts that make up
a full trait definition.

 * `pub` or `pub (restriction)` - (optional) A visibility specification.  This
 isn't strictly a part of the trait's info, but will determine the visibility of
 the generated macro and trait re-export that is generated as a side-effect of
 this macro.

 * `trait` - just the keyword `trait`.

 * `<'a, T, const N: usize, ...>` - (optional) generic parameters, as would be
 found after the type identifier in a normal trait definition.  Any default
 values will be ignored, and should not be provided.

 * `where T: 'a, ...` - (optional) a where clause, as would be found in the
 trait definition.

 * `{type Error; fn try_from (x: T) -> Result <Self, Self::Error>; ...}` - A
 block containing the definitions of the trait items.  Again, any default values
 (or implementations) will be ignored, and should not be provided.

All types included should be named by their fully-qualified paths whenever
applicable.

# Mechanism

The way that this attribute works is by defining a macro which can be used to
uncurry the trait forwarding information into another macro.

Due to limitations of macro export rules, a mangled version of that macro's name
is also created and exported into the crate root.  While these names are mangled
so that they're unlikely to cause name collisions, annotating trait definitions
of the same name in two different modules of the same crate will _definitely_
cause a problem.  Please keep trait names within a single crate unique.

# Example

```rust
# use forward_traits::{supply_forwarding_info_for_trait, forward_receiver, forward_traits_via_conversion};
supply_forwarding_info_for_trait!
(
	std::iter::FromIterator,
	pub (crate) trait <A>
	{
		fn from_iter <T> (iter: T) -> Self
		where T: IntoIterator <Item = A>;
	}
);
# #[forward_receiver]
# struct VecWrapper <T> (Vec <T>);
# impl <T> From <Vec <T>> for VecWrapper <T> { fn from (vec: Vec <T>) -> Self { Self (vec) } }
# forward_traits_via_conversion! (VecWrapper -> Vec <T>, FromIterator <T>);
```

*/
#[proc_macro]
pub fn supply_forwarding_info_for_trait (input: TokenStream) -> TokenStream
{
	supply_trait_info::supply_forwarding_info_for_trait_impl (input)
}

#[doc (hidden)]
#[proc_macro]
pub fn __forward_trait_via_conversion (input: TokenStream) -> TokenStream
{
	forward_via_conversion::__forward_trait_via_conversion_impl (input)
}

/**

This macro generates trait implementations based on conversions from the
implementing type to a delegated type which already implements the trait.

# Usage

The first argument to the macro is a specification of the base type and the
delegated type.  This specification has the form `BaseTypeIdent ->
path::to::DelegatedType`.

The remaining arguments are descriptions of traits that should be forwarded.
The trait generic arguments, if any, will be interpreted as if the generic
parameters from the base type are in scope.

If a trait would need additional generic arguments to be introduced in order to
correctly specify the trait's generic parameters, these arguments can be
provided by prefixing the trait path with a quantifier over those parameters.
The syntax is similar to that of
Higher-Ranked Trait Bounds, except that all forms of generic parameters are
supported.  These parameters will be introduced into the `impl` scope along with
the generic parameters of the receiver type, so make sure that their names don't
collide with the receiver type's generic parameters.

Additionally, if additional where predicates need to be provided on top of those
found in the type definition and trait definition (and besides those which could
be provided automatically by the forwarding macro), then those may also be
introduced by suffixing the trait path with a where clause.  If a where clause
is included, the where clause must be followed by a semicolon.

Putting that all together, a description of a trait to be forwarded might look
like this: `for <'a> path::to::Trait <&'a [T]> where T: 'a;`.

# Example

```rust
# use forward_traits::supply_forwarding_info_for_trait;
#
# supply_forwarding_info_for_trait!
# (
# 	std::iter::IntoIterator,
# 	trait
# 	{
# 		type Item;
# 		type IntoIter;
#
# 		fn into_iter (self) -> Self::IntoIter;
# 	}
# );
#
# supply_forwarding_info_for_trait!
# (
# 	std::convert::TryFrom,
# 	trait <T>
# 	{
# 		type Error;
#
# 		fn try_from (value: T) -> std::result::Result <Self, Self::Error>;
# 	}
# );
#
use forward_traits::{forward_receiver, forward_traits_via_conversion};

#[derive (Debug)]
#[forward_receiver]
struct Point
{
	x: f32,
	y: f32
}

impl From <Point> for [f32; 2]
{
	fn from (p: Point) -> [f32; 2]
	{
		[p . x, p . y]
	}
}

impl From <[f32; 2]> for Point
{
	fn from (a: [f32; 2]) -> Self
	{
		Self {x: a [0], y: a [1]}
	}
}

// Make sure that the traits we want are annotated.  In this case, we've
// annotated some std traits and imported them into the local scope.

forward_traits_via_conversion! (Point -> [f32; 2], for <'a> TryFrom <&'a [f32]>, IntoIterator);

// Now we can do weird stuff, life try to construct Point from slices.

Point::try_from ([1f32, 2f32] . as_slice ()) . unwrap () . into_iter ();
Point::try_from ([1f32] . as_slice ()) . unwrap_err ();
```

# Conversions

Up to 4 different conversions may be used.  If `BaseType` were to forward an
implementation by `DelegatedType`, those conversions would be:

 * `<BaseType as std::convert::AsRef <DelegatedType>>::borrow ()` for function
 arguments of type `&Self`.

 * `<BaseType as std::convert::AsMut <DelegatedType>>::borrow_mut ()` for
 function arguments of type `&mut Self`.

 * `<BaseType as std::convert::Into <DelegatedType>>::into ()` for function
 arguments of type `Self`.

 * `<BaseType as std::convert::From <DelegatedType>>::from ()` for a return type
 of `Self`.

Any conversion that is actually used to forward a trait implementation will need
to be implemented for the receiving type.  Any conversion that is not used does
not need to be implemented.

In practice, if a trait implementation would only use borrowing conversions, it
might make more sense to use a member forward instead, as that doesn't require
that the receiver type implement any conversion traits.

Note that forwarding via conversion is the only way to forward a trait that has
a method that returns `Self` in any form.

All arguments to a trait method that have a type of some form of self are
converted, not just the method receiver.  This also allows traits to be
forwarded that require/provide methods that don't take a receiver, but still
take arguments of the receiver type.

Self types in container types like `Result` and `Box` are also converted.

*/
#[proc_macro]
pub fn forward_traits_via_conversion (input: TokenStream) -> TokenStream
{
	forward_via_conversion::forward_traits_via_conversion_impl (input)
}

#[doc (hidden)]
#[proc_macro]
pub fn __forward_trait_via_member (input: TokenStream) -> TokenStream
{
	forward_via_member::__forward_trait_via_member_impl (input)
}

/**

This macro generates trait implementations for a type where a member of that
type implements the trait.

# Usage

The first argument to the macro is a specification of which member should
provide the implementation of the forwarded trait.  This specification takes the
form `BaseTypeIdent . member`, where `member` is either an identifier or an
index, as appropriate for the type.

The remaining arguments are descriptions of traits that should be forwarded.
The trait generic arguments, if any, will be interpreted as if the generic
parameters from the base type are in scope.

If a trait would need additional generic arguments to be introduced in order to
correctly specify the trait's generic parameters, these arguments can be
provided by prefixing the trait path with a quantifier over those parameters.
The syntax is similar to that of
Higher-Ranked Trait Bounds, except that all forms of generic parameters are
supported.  These parameters will be introduced into the `impl` scope along with
the generic parameters of the receiver type, so make sure that their names don't
collide with the receiver type's generic parameters.

Additionally, if additional where predicates need to be provided on top of those
found in the type definition and trait definition (and besides those which could
be provided automatically by the forwarding macro), then those may also be
introduced by suffixing the trait path with a where clause.  If a where clause
is included, the where clause must be followed by a semicolon.

Putting that all together, a description of a trait to be forwarded might look
like this: `for <'a> path::to::Trait <&'a [T]> where T: 'a;`.

# Example

```rust
# use forward_traits::supply_forwarding_info_for_trait;
#
# supply_forwarding_info_for_trait!
# (
# 	std::ops::Index,
# 	trait <Idx>
# 	{
# 		type Output;
#
# 		fn index (&self, index: Idx) -> &Self::Output;
# 	}
# );
#
# supply_forwarding_info_for_trait!
# (
# 	std::ops::IndexMut,
# 	trait <Idx>
# 	where Self: Index <Idx>
# 	{
# 		fn index_mut (&mut self, index: Idx) -> &mut Self::Output;
# 	}
# );
#
use forward_traits::{forward_receiver, forward_traits_via_member};

#[forward_receiver]
struct Foo
{
	header: [u8; 4],
	items: Vec <u8>
}

forward_traits_via_member! (Foo . items, Index <usize>, IndexMut <usize>);
```

# Conversions

Conversions are performed via member access.  Return types cannot be converted,
as member access has no inverse.

All arguments to a trait method that have a type of some form of self are
converted, not just the method receiver.  This also allows traits to be
forwarded that require/provide methods that don't take a receiver, but still
take arguments of the receiver type.

Self types in container types like `Result` and `Box` are also converted.

*/
#[proc_macro]
pub fn forward_traits_via_member (input: TokenStream) -> TokenStream
{
	forward_via_member::forward_traits_via_member_impl (input)
}