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
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
//!
//! # Ambassador - Delegate trait implementations via procedural macros
//!
//! <!-- Crates version -->
//! <a href="https://crates.io/crates/ambassador">
//!   <img src="https://img.shields.io/crates/v/ambassador.svg?style=flat-square"
//!   alt="Crates.io version" />
//! </a>
//! <!-- docs.rs docs -->
//! <a href="https://docs.rs/ambassador">
//!   <img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square"
//!     alt="docs.rs docs" />
//! </a>
//!
//! <br/>
//!
//!
//! Delegating the implementation of traits to enum variants or fields of a struct normally requires a lot of boilerplate code. Ambassador is an attempt to eliminate that boilerplate by deriving the delegating trait implementation via procedural macros.
//!
//! **The minimum supported Rust version is 1.53.0.**
//!
//! See individual macro documentation for detailed instructions.
//!
//! This is one example combining a large number of features:
//!
//! ```
//! extern crate ambassador;
//!
//! use std::collections::{HashMap, BTreeMap};
//! use std::borrow::Borrow;
//! use std::cmp::{Eq, Ord};
//! use std::hash::{Hash, BuildHasher};
//! use std::ops::Deref;
//! use ambassador::{delegatable_trait, delegate_remote, delegate_to_remote_methods, Delegate};
//!
//! #[delegatable_trait]
//! pub trait Map {
//!     type K;
//!     type V;
//! }
//!
//! #[delegatable_trait]
//! pub trait Get<Q: ?Sized>: Map {
//!     fn get(&self, k: &Q) -> Option<&Self::V>;
//! }
//!
//! impl<K, V, S> Map for HashMap<K, V, S>  {
//!     type K = K;
//!     type V = V;
//! }
//!
//! impl<K, V> Map for BTreeMap<K, V>  {
//!     type K = K;
//!     type V = V;
//! }
//!
//!
//! // No automatic where clause provided for target = "self"
//! #[delegate_remote]
//! #[delegate(Get<X>, target = "self", generics = "X", where = "K: Hash + Eq + Borrow<X>, S: BuildHasher, X: Hash + Eq + ?Sized")]
//! struct HashMap<K, V, S>();
//!
//! #[delegate_remote]
//! #[delegate(Get<X>, target = "self", generics = "X", where = "K: Ord + Borrow<X>, X: Ord + ?Sized")]
//! struct BTreeMap<K, V>();
//!
//! #[derive(Delegate)]
//! #[delegate(Map)]
//! #[delegate(Get<X>, generics = "X", where = "X: ?Sized, B: Map<K=A::K, V=A::V>")]  //auto where clause misses required on super trait
//! pub enum Either<A, B> {
//!     Left(A),
//!     Right(B),
//! }
//!
//! #[delegate_to_remote_methods]
//! #[delegate(Map, target_ref = "deref")]
//! impl<M: ?Sized + Map> Map for Box<M> {
//!     fn deref(&self) -> &M;
//! }
//!
//! fn takes_map(_m: &impl Map<K = &'static str, V = u32>) { }
//!
//! pub fn main() {
//!     let my_map: Either<HashMap<&'static str, u32>, BTreeMap<&'static str, u32>> = Either::Left([("a", 1)].into());
//!     assert_eq!(my_map.get("a"), Some(&1));
//!
//!     let boxed: Box<dyn Map<K = &'static str, V = u32>> = Box::new(my_map);
//!     takes_map(&boxed);
//! }
//! ```
//!
//! # Backwards Compatibility
//! Since delegateable traits from one crate can be used in anther crate backwards compatibility of switching to 0.3.x depends on the use case
//! ## Self Contained Crate
//! Switching to 0.3.x should just work,
//! in this case it safe to disable the "backward_compatible" feature
//! ## Library with public delegatable traits
//! Make sure use the "backward_compatible" feature (enabled by default),
//! this makes sure users of your library using an older version of ambassador aren't affected by the upgrade
//! ## Users of a library with public delegatable traits
//! Try to use the same version of ambassador as the library you're using

extern crate core;
extern crate proc_macro;

mod delegate_shared;
mod delegate_to_methods;
mod derive;
mod register;
mod util;

use proc_macro::TokenStream;
use quote::quote;

use crate::register::build_register_trait;

/// Delegate the implementation of a trait to a struct field/enum variants by adding `#[derive(Delegate)]` and its associated attribute `#[delegate(Trait)]` to it:
///
/// ```
/// use ambassador::{Delegate, delegatable_trait};
///
/// #[delegatable_trait]
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
///
/// pub struct Cat;
///
/// impl Shout for Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// #[derive(Delegate)] // <-------
/// #[delegate(Shout)] // <-------- Delegate implementation of Shout to struct field
/// pub struct WrappedCat(Cat);
/// ```
///
///#### `#[delegate(..., target = "foo")]` - `target` key
///
/// For structs with multiple fields, the field that should act as delegation target can be specified via the `target` key:
///
/// ```
/// # use ambassador::{Delegate, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// # pub struct Cat;
/// #
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String {
/// #         format!("{} - meow!", input)
/// #     }
/// # }
///
/// #[derive(Delegate)]
/// #[delegate(Shout, target = "foo")] // <-------- Delegate implementation of Shout to struct field .foo
/// pub struct WrappedCats {
///   foo: Cat,
///   bar: Cat,
/// }
/// ```
/// This also works for tuple structs with multiple fields, by using their index as a target key:
///
/// ```
/// # use ambassador::{Delegate, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// # pub struct Cat;
/// #
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String {
/// #         format!("{} - meow!", input)
/// #     }
/// # }
///
/// #[derive(Delegate)]
/// #[delegate(Shout, target = "1")] // <-------- Delegate implementation of Shout to second field
/// pub struct WrappedCats(Cat, Cat);
/// ```
///
/// #### `#[delegate(..., target = "self")]` - `target="self"`
/// Types that implement all the methods of a trait without implementing the trait itself,
/// can be made to implement that trait by setting `target="self"`.
/// This doesn't work for traits with associated types and constants, and requires the where clause to be added explicitly (see `where` key).
/// If the type doesn't actually implement the methods (possibly due to an incomplete `where` clause) this can cause a `[unconditional_recursion]` error.
///
/// A possible use case of this is when refactoring some methods of a public type into a trait,
/// the type still needs to implement the methods outside the trait for semver reasons,
/// and using this feature reduces the boilderplate of implementing the trait with the same methods.
///
///
/// ```
/// # use ambassador::{Delegate, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// #[derive(Delegate)]
/// #[delegate(Shout, target="self")]
/// pub struct Cat;
///
/// impl Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
/// ```
///
/// #### `#[delegate(..., where = "A: Debug")]` - `where` key
///
/// To make a delegation apply only for certain generic bounds, similar to a [native where clause](https://doc.rust-lang.org/stable/rust-by-example/generics/where.html), you can specify a `where` attribute:
///
/// A where clause is automatically applied that makes sure the target field implements the trait being delegated
/// ```
/// # use ambassador::{Delegate, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// use std::fmt::Debug;
///
/// #[derive(Delegate)]
/// #[delegate(Shout, where = "A: Debug")] // <---- Delegate implementation of Shout to .foo field if foo field implements Debug
/// // "A: Shout" is automatically added
/// pub struct WrappedFoo<A> {
///   foo: A,
/// }
/// ```
///
///
/// #### `#[delegate(Shout<X>, generics = "X")]` - trait generics
///
/// We can also delegate traits with generics.
/// The type parameters listed in the `generics` key are treated as fully generic.
/// The automatically added where clause ensures they are valid for the inner type being delegated to.
/// Explict where clauses to further refine these types can be added as normal.
///
/// ```
/// use ambassador::{delegatable_trait, Delegate};
/// use std::fmt::Display;
///
/// #[delegatable_trait]
/// pub trait Shout<T> {
///     fn shout(&self, input: T) -> String;
/// }
///
/// pub struct Cat;
///
/// impl<T: Display> Shout<T> for Cat {
///     fn shout(&self, input: T) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// #[derive(Delegate)]
/// #[delegate(Shout<X>, generics = "X")] // <-------- `X` is fully generic
/// // The automatic where clause ensures X: Display
/// // We could also use #[delegate(Shout<& 'a str>, generics = "'a")] to only delegate for &str
/// pub struct WrappedCat(Cat);
/// ```
///
///
/// #### `#[delegate(Shout, automatic_where_clause = "false")]` - inhibit automatic generation of `where` clause.
///
/// Normally `#[derive(Delegate)]` generates code to ensure that chosen field
/// indeed implements the trait you want to implement for the container struct.
///
/// For example, the `#[derive(Delegate)]` + `#[delegate(Shout<X>, generics = "X")]`
/// in the example above will emit code that requires `Cat` (the type we're
/// delegating to) to implement `Shout<X>`: `Cat: Shout<X>`.
///
/// However, you may want to delegate implementation to a type that does not in
/// fact fully implement the trait in question but instead has _compatible
/// methods_ that can be called as if the trait were in fact implemented.
///
/// One notable examples of this is delegating a trait implementation to
/// container types holding a trait object; i.e. `MyTrait` for
/// `Box<dyn MyTrait>`. In this example, `Box<dyn MyTrait`
/// [`Deref`](core::ops::Deref)s into `dyn MyTrait` which provides `MyTrait`s
/// methods; this allows us effectively just call `MyTrait`s methods directly
/// on `Box<dyn MyTrait>` even though `Box<dyn MyTrait>` does not actually
/// implement `MyTrait`.
///
/// `automatic_where_clause = "false"` lets us create a delegated impl of
/// `MyTrait` that takes advantage of this.
///
/// ```
/// use ambassador::{delegatable_trait, Delegate};
/// use std::fmt::Display;
///
/// #[delegatable_trait]
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
///
/// pub struct Cat;
///
/// impl Shout for Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// #[derive(Delegate)]
/// #[delegate(Shout, automatic_where_clause = "false")]
/// pub struct BoxedAnimal(pub Box<dyn Shout + Send + Sync>);
///
/// // Can accept both `Cat` and `BoxedAnimal`.
/// fn recording_studio<S: Shout>(voice_actor: S){}
/// ```
///
/// Note that it is also possible to create such a delegated impl by making use
/// of [`macro@delegate_to_remote_methods`] with [`Deref::deref`] and
/// [`DerefMut::deref_mut`] as the target methods. The docs on
/// [`macro@delegate_to_remote_methods`] contain an example of this.
///
/// [`Deref::deref`]: core::ops::Deref::deref
/// [`DerefMut::deref_mut`]: core::ops::DerefMut::deref_mut
#[proc_macro_derive(Delegate, attributes(delegate))]
pub fn delegate_macro(input: TokenStream) -> TokenStream {
    derive::delegate_macro(input)
}

/// Delegate the implementation of a trait to a type's methods by adding `#[delegate_to_methods]` and its associated attribute `#[delegate(Trait)]` to the relevant impl block
///
/// #### `#[delegate(..., target_owned = "foo", target_ref = "bar", target_mut = "baz")]` - `target` keys
/// Three different target methods can be specified depending on the receiver of of the trait method being delegated.
/// These methods must have the signatures target_owned: "fn foo(self) -> X", target_ref: "fn bar(&self) -> &X", and target_mut: "fn baz(&mut self) -> &mut X"
/// where X is the same type for all three.
/// Excluding some of these attributes is allowed as long as the trait being delegated to doesn't have any methods with the relevant receiver
/// Additional methods that don't have any of the relevant signature types may be included in the impl block as long as they are never used as targets.
///
/// #### The `where` and `generics` keys described in [`Delegate`] are also supported and function the same way
///
/// ```
/// use std::ops::{Deref, DerefMut};
/// use ambassador::{delegate_to_methods, delegatable_trait};
///
/// #[delegatable_trait]
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
///
/// pub struct Cat;
///
/// impl Shout for Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// pub struct BoxedCat(Box<Cat>); // Target is hidden behind a box
///
/// #[delegate_to_methods]
/// #[delegate(Shout, target_ref = "inner", target_mut = "inner_mut")]
/// impl BoxedCat {
///    fn inner(&self) -> &Cat {
///         self.0.deref()
///     }
///
///     // Note we don't need target_mut = "inner_mut" in this case but it is included as an example
///     // The return type must be &mut Cat to match inner's return type &Cat
///     fn inner_mut(&mut self) -> &mut Cat {
///         self.0.deref_mut()
///     }
///
///     // You can also have extra methods here:
///     fn another_one(&self) { }
/// }
/// ```
///
/// #### `delegate_to_methods` on an `impl Trait for ...` block
///
/// It's also valid to use `delegate_to_methods` with a trait impl; i.e. to use
/// the methods from a different trait to delegate a trait. For example:
/// ```
/// # use std::ops::{Deref, DerefMut};
/// # use ambassador::{delegate_to_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String {
/// #         format!("{} - meow!", input)
/// #     }
/// # }
///
/// pub struct RefCat<'a>(&'a Cat);
///
/// #[delegate_to_methods]
/// #[delegate(Shout, target_ref = "deref")]
/// impl<'a> Deref for RefCat<'a> {
///     type Target = Cat;
///
///     fn deref(&self) -> &Cat { &self.0 }
/// }
/// ```
///
/// Note that this has a caveat: if the target methods you are delegating to
/// share the same name as any of the methods in the trait being delegated you
/// will likely get errors about ambiguity. For example:
///
/// ```rust,compile_fail
/// # use std::ops::{Deref, DerefMut};
/// # use ambassador::{delegate_to_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String {
/// #         format!("{} - meow!", input)
/// #     }
/// # }
///
/// pub struct RefCat<'a>(&'a Cat);
///
/// trait GetAShouter {
///   type Shouter: Shout;
///
///   fn shout(&self) -> &Self::Shouter;
/// }
///
/// #[delegate_to_methods]
/// #[delegate(Shout, target_ref = "shout")]
/// impl<'a> GetAShouter for RefCat<'a> {
///     type Shouter = Cat;
///
///     fn shout(&self) -> &Cat { &self.0 }
/// }
/// ```
///
/// Yields:
/// ```text
/// error[E0034]: multiple applicable items in scope
///   --> src/lib.rs:363:32
///    |
/// 26 | #[delegate(Shout, target_ref = "shout")]
///    |                                ^^^^^^^ multiple `shout` found
///    |
/// note: candidate #1 is defined in an impl of the trait `Shout` for the type `RefCat<'a>`
///   --> src/lib.rs:345:5
///    |
/// 8  |     fn shout(&self, input: &str) -> String;
///    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/// ...
/// 25 | #[delegate_to_methods]
///    | ---------------------- in this procedural macro expansion
/// note: candidate #2 is defined in an impl of the trait `GetAShouter` for the type `RefCat<'a>`
///   --> src/lib.rs:367:5
///    |
/// 30 |     fn shout(&self) -> &Cat { &self.0 }
///    |     ^^^^^^^^^^^^^^^^^^^^^^^
///    = note: this error originates in the macro `ambassador_impl_Shout` (in Nightly builds, run with -Z macro-backtrace for more info)
/// ```
///
/// This is not an issue when the target methods are _inherent_ since inherent
/// methods explicitly [have priority over trait methods](https://dtolnay.github.io/rust-quiz/23)
/// during method resolution.
///
/// The workaround is to create wrapper inherent methods for the trait's methods:
/// ```
/// # use std::ops::{Deref, DerefMut};
/// # use ambassador::{delegate_to_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout {
/// #     fn shout(&self, input: &str) -> String;
/// # }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String {
/// #         format!("{} - meow!", input)
/// #     }
/// # }
///
/// pub struct RefCat<'a>(&'a Cat);
///
/// trait GetAShouter {
///   type Shouter: Shout;
///
///   fn shout(&self) -> &Self::Shouter;
/// }
///
/// impl<'a> GetAShouter for RefCat<'a> {
///     type Shouter = Cat;
///
///     fn shout(&self) -> &Cat { &self.0 }
/// }
///
/// #[delegate_to_methods]
/// #[delegate(Shout, target_ref = "get_a_shouter")]
/// impl<'a> RefCat<'a> { fn get_a_shouter(&self) -> &Cat { GetAShouter::shout(self) } }
/// ```
#[proc_macro_attribute]
pub fn delegate_to_methods(_attr: TokenStream, input: TokenStream) -> TokenStream {
    delegate_to_methods::delegate_macro(input, true)
}

/// Delegate the implementation of a trait to methods on a type that are defined
/// _elsewhere_.
///
/// This macro is identical to [`macro@delegate_to_methods`] except that it does not
/// actually produce an `impl` block on the type for the target methods; instead
/// it assumes that the methods are implemented elsewhere.
/// ```
/// use ambassador::{delegate_to_remote_methods, delegatable_trait};
///
/// #[delegatable_trait]
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
///
/// pub struct Cat;
///
/// impl Shout for Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// pub struct BoxedCat(Box<Cat>);
///
/// impl BoxedCat {
///    fn inner(&self) -> &Cat { &self.0 }
/// }
///
/// #[delegate_to_remote_methods]
/// #[delegate(Shout, target_ref = "inner")]
/// impl BoxedCat {
///     // `inner` can be defined anywhere: trait method or inherent method, in
///     // this crate or elsewhere
///     fn inner(&self) -> &Cat;
/// }
/// ```
///
/// As such, this macro will actually error if you provide it with methods with
/// blocks, method signatures that aren't used by a `delegate` attribute on the
/// impl, or other impl items:
/// ```rust,compile_fail
/// # use ambassador::{delegate_to_remote_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout { fn shout(&self, input: &str) -> String; }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String { format!("{} - meow!", input) }
/// # }
/// # pub struct BoxedCat(Box<Cat>);
/// # impl BoxedCat { fn inner(&self) -> &Cat { &self.0 } }
///
/// #[delegate_to_remote_methods]
/// #[delegate(Shout, target_ref = "inner")]
/// impl BoxedCat {
///     fn inner(&self) -> &Cat { &self.0 } // This is an error, method bodies
///                                         // aren't accepted
///
///     fn extra(&self);                    // Extra methods are also error since no
///                                         // `impl BoxedCat { ... }` is actually
///                                         // emitted
///
///     const CONST: () = ();               // This is also an error.
/// }
/// ```
///
/// Target methods can come from a trait or be inherent methods whose actual
/// implementation lives elsewhere. You can mix and match:
/// ```
/// # use ambassador::{delegate_to_remote_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout { fn shout(&self, input: &str) -> String; }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String { format!("{} - meow!", input) }
/// # }
/// # pub struct BoxedCat(Box<Cat>);
/// # impl BoxedCat { fn inner(&self) -> &Cat { &self.0 } }
/// use std::ops::{Deref, DerefMut};
///
/// impl Deref for BoxedCat {
///     type Target = Cat;
///
///     fn deref(&self) -> &Self::Target { &self.0 }
/// }
///
/// impl DerefMut for BoxedCat {
///     fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
/// }
///
/// #[delegate_to_remote_methods]
/// #[delegate(Shout, target_ref = "inner", target_mut = "deref_mut")]
/// impl BoxedCat {
///     fn inner(&self) -> &Cat;
///     fn deref_mut(&mut self) -> &mut Cat;
/// }
/// ```
/// Note that if you do use target methods from a trait, the trait must be in
/// scope.
///
/// Because this macro does not implement any inherent methods on the type being
/// delegated to, the type can be remote (like with [`macro@delegate_remote`]):
/// ```
/// # use ambassador::{delegate_to_remote_methods, delegatable_trait};
/// # #[delegatable_trait]
/// # pub trait Shout { fn shout(&self, input: &str) -> String; }
/// # pub struct Cat;
/// # impl Shout for Cat {
/// #     fn shout(&self, input: &str) -> String { format!("{} - meow!", input) }
/// # }
/// use std::ops::{Deref, DerefMut};
///
/// // Note that this impl says `Deref for Box<Cat>`.
/// //
/// // The trait in this impl is ignored and only serves as documentation here.
/// #[delegate_to_remote_methods]
/// #[delegate(Shout, target_ref = "deref")]
/// impl Deref for Box<Cat> {
///     fn deref(&self) -> &Cat;
/// }
///
/// fn shout(_: &impl Shout) { }
///
/// fn main() {
///     let c = Cat;
///     shout(&c);
///
///     let boxed: Box<Cat> = Box::new(c);
///     shout(&boxed);
/// }
/// ```
///
/// This can be used in conjunction with generics to provide blanket delegated
/// implementations of a local trait without needing to create intermediary
/// local traits that provide target methods to use:
/// ```
/// # use ambassador::{delegatable_trait, delegate_to_remote_methods};
/// # use std::ops::{Deref, DerefMut};
/// # #[delegatable_trait]
/// # pub trait Shout { fn shout(&self, input: &str) -> String; }
/// # pub struct Cat;
/// # impl Shout for Cat { fn shout(&self, input: &str) -> String { format!("{} - meow!", input) } }
/// use std::{sync::Arc, rc::Rc};
///
/// pub struct Dog;
/// impl Shout for Dog {
///     fn shout(&self, input: &str) -> String { format!("{} - wuff!", input) }
/// }
///
/// #[delegate_to_remote_methods]
/// #[delegate(Shout, target_ref = "deref")]
/// impl<S: ?Sized + Shout, T: Deref<Target = S>> T {
///     fn deref(&self) -> &S;
/// }
///
/// pub fn shout(pet: &impl Shout) { println!("{}", pet.shout("hi")); }
///
/// pub fn main() {
///     shout(&Cat);
///     shout(&Dog);
///
///     let a: Box<dyn Shout> = Box::new(Cat);
///     let b: Arc<dyn Shout + Send> = Arc::new(Dog);
///     let c: Rc<dyn Shout + Send + Sync + 'static> = Rc::new(Cat);
///     shout(&a);
///     shout(&b);
///     shout(&c);
///
///     let d: Box<Cat> = Box::new(Cat);
///     shout(&d);
/// }
/// ```
#[proc_macro_attribute]
pub fn delegate_to_remote_methods(_attr: TokenStream, input: TokenStream) -> TokenStream {
    delegate_to_methods::delegate_macro(input, false)
}

/// Make an existing type that lives outside you crate delegate traits to it's members
///
/// This can be done by copy-pasting it's definition into your code under this attribute.
///
/// If the type is a struct, not all the fields have to be public, only the ones being delegated to.
///
/// ```
/// use ambassador::{delegate_remote, delegatable_trait};
///
/// #[delegatable_trait]
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
///
/// pub struct Cat;
///
/// impl Shout for Cat {
///     fn shout(&self, input: &str) -> String {
///         format!("{} - meow!", input)
///     }
/// }
///
/// mod wrapped {
///     pub struct WrappedAnimals<A, B> {
///         pub foo: A,
///         pub bar: B,
///         baz: u32, // private field
///     }
/// }
///
/// use wrapped::*;
///
/// #[delegate_remote]
/// #[delegate(Shout, target = "bar")]
/// struct WrappedAnimals<A, B> {
///     foo: A,
///     bar: B,
///     // We don't even have to include baz since we don't delegate to it
/// }
/// ```
#[proc_macro_attribute]
pub fn delegate_remote(_attr: TokenStream, input: TokenStream) -> TokenStream {
    derive::delegate_macro(input)
}

/// Make a trait available for delegation
///
/// This also makes your trait delegatable in other crates:
///
/// ```
/// use ambassador::delegatable_trait;
///
/// #[delegatable_trait] // <-------
/// pub trait Shout {
///     fn shout(&self, input: &str) -> String;
/// }
/// ```
#[proc_macro_attribute]
pub fn delegatable_trait(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let original_item: syn::ItemTrait = syn::parse(item).unwrap();
    let register_trait = build_register_trait(&original_item);

    let expanded = quote! {
        #original_item

        #register_trait
    };
    TokenStream::from(expanded)
}

/// Make an existing trait that lives outside you crate available for delegation.
///
/// This can be done by copy-pasting the existing traits signature into your code under this attribute
///
/// ```
/// use ambassador::{Delegate, delegatable_trait_remote};
/// use std::fmt::Display;
///
/// #[delegatable_trait_remote]
/// trait Display {
///     fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>;
/// }
///
/// struct Cat;
///
/// impl Display for Cat {
///     fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error>{
///         f.write_str("Cat")
///     }
/// }
///
/// #[derive(Delegate)]
/// #[delegate(Display)] // <-------- Delegate implementation of Display to struct field
/// pub struct WrappedCat(Cat);
/// ```
#[proc_macro_attribute]
pub fn delegatable_trait_remote(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let original_item: syn::ItemTrait = syn::parse(item).unwrap();
    let register_trait = build_register_trait(&original_item);

    let expanded = quote! {
        #register_trait
    };
    TokenStream::from(expanded)
}