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
//! Inherit and derive object-unsafe traits for dynamic Rust.
//!
//! ## Introduction
//!
//! [Object safety](https://doc.rust-lang.org/reference/items/traits.html#object-safety) is a property of traits in Rust that determines whether the trait can be used as a trait object. However, there are many useful traits that are not object-safe, such as `Clone` and `PartialEq`.
//!
//! For example, you cannot simply write:
//!
//! ```compile_fail
//! pub trait Meta: Clone + PartialEq {}
//!
//! #[derive(Clone, PartialEq)]
//! pub struct Foo {
//! meta: Box<dyn Meta>, // The trait `Meta` cannot be made into an object.
//! }
//! ```
//!
//! This crate provides a procedural macro for deriving object-unsafe traits:
//!
//! ```
//! use dynex::*;
//!
//! #[dyn_trait]
//! pub trait Meta: Clone + PartialEq {}
//!
//! #[derive(Clone, PartialEqFix)]
//! pub struct Foo {
//! meta: Box<dyn Meta>, // Now it works!
//! }
//! ```
//!
//! Note: `PartialEqFix` has the exact same behavior as `PartialEq`, but it workarounds a strange behavior of the Rust compiler. For other traits, you can just derive the original trait name.
//!
//! ## Basic Example
//!
//! Below is a basic example of how to use this crate:
//!
//! ```
//! use std::fmt::Debug;
//! use dynex::*;
//!
//! #[dyn_trait]
//! pub trait Meta: Debug + Clone + PartialEq {
//! fn answer(&self) -> i32 {
//! 42
//! }
//! }
//!
//! #[derive(Debug, Clone, PartialEq)]
//! pub struct MetaImpl;
//!
//! impl Meta for MetaImpl {}
//!
//! #[derive(Debug, Clone, PartialEqFix)]
//! pub struct Foo {
//! meta: Box<dyn Meta>,
//! }
//!
//! fn main() {
//! let foo1 = Foo { meta: Box::new(MetaImpl) };
//! let foo2 = Foo { meta: Box::new(MetaImpl) };
//! assert_eq!(foo1, foo2);
//! let foo3 = foo1.clone();
//! assert_eq!(foo3.meta.answer(), 42);
//! }
//! ```
//!
//! ## Non-Derivable Traits
//!
//! Taking the `Add` trait as an example:
//!
//! ```
//! use std::fmt::Debug;
//! use std::ops::Add;
//! use dynex::*;
//!
//! #[dyn_trait]
//! pub trait Meta: Debug + Add {}
//!
//! #[derive(Debug)]
//! pub struct MetaImpl(String);
//!
//! impl Meta for MetaImpl {}
//!
//! impl Add for MetaImpl {
//! type Output = Self;
//!
//! fn add(self, rhs: Self) -> Self {
//! Self(self.0 + &rhs.0)
//! }
//! }
//!
//! pub struct Foo {
//! pub meta: Box<dyn Meta>,
//! }
//!
//! impl Add for Foo {
//! type Output = Self;
//!
//! fn add(self, rhs: Self) -> Self {
//! Self {
//! // `Box<dyn Meta>` can be added!
//! meta: self.meta + rhs.meta,
//! }
//! }
//! }
//!
//! fn main() {
//! let foo1 = Foo { meta: Box::new(MetaImpl("114".into())) };
//! let foo2 = Foo { meta: Box::new(MetaImpl("514".into())) };
//! let foo3 = foo1 + foo2;
//! println!("{:?}", foo3.meta); // MetaImpl("114514")
//! }
//! ```
use TokenStream;
/// This derive macro has the exact same behavior as `PartialEq`,
/// but it workarounds a strange behavior of the Rust compiler.
///
/// For other traits, you can just derive the original trait name.
///
/// ## Example
///
/// ```
/// use dynex::*;
///
/// #[dyn_trait]
/// pub trait Meta: Clone + PartialEq {}
///
/// #[derive(Clone, PartialEqFix)]
/// pub struct Foo {
/// meta: Box<dyn Meta>,
/// }
/// ```
/// This is a procedural macro for deriving object-unsafe traits.
///
/// ## Example
///
/// `Clone` is not object-safe, but with this macro, you can still use `dyn Meta`:
///
/// ```
/// use dynex::*;
///
/// #[dyn_trait]
/// pub trait Meta: Clone {}
///
/// #[derive(Clone)]
/// pub struct Foo {
/// meta: Box<dyn Meta>,
/// }
/// ```