@@ -22,7 +22,7 @@ fn scan_to_string_fn(field: &Field) -> Result<Option<proc_macro2::TokenStream>>
22
22
if filtered. is_empty ( ) {
23
23
Ok ( None )
24
24
} else {
25
- Ok ( Some ( filtered[ 0 ] . tokens . clone ( ) ) )
25
+ Ok ( Some ( filtered[ 0 ] . parse_args ( ) ? ) )
26
26
}
27
27
}
28
28
@@ -35,7 +35,7 @@ fn has_use_to_string(field: &Field) -> Result<bool> {
35
35
if filtered. clone ( ) . any ( |a| !a. tokens . is_empty ( ) ) {
36
36
return Err ( Error :: new (
37
37
field. span ( ) ,
38
- "[IntoEvent] attribute `use_to_string` has some value. If you intend to specify the cast function to string, use `to_string_fn` instead." ,
38
+ "[IntoEvent] An attribute `use_to_string` has some value. If you intend to specify the cast function to string, use `to_string_fn` instead." ,
39
39
) ) ;
40
40
}
41
41
Ok ( filtered. next ( ) . is_some ( ) )
@@ -88,12 +88,11 @@ fn make_init_from_struct(id: Ident, struct_data: DataStruct) -> Result<proc_macr
88
88
Ok ( gen)
89
89
}
90
90
91
- /// derive `IntoEvent` from a derive input. The input needs to be a struct.
92
- pub fn derive_into_event ( input : DeriveInput ) -> TokenStream {
91
+ fn derive_into_event_impl ( input : DeriveInput ) -> proc_macro2:: TokenStream {
93
92
match input. data {
94
- syn:: Data :: Struct ( struct_data) => make_init_from_struct ( input . ident , struct_data )
95
- . unwrap_or_else ( |e| e. to_compile_error ( ) )
96
- . into ( ) ,
93
+ syn:: Data :: Struct ( struct_data) => {
94
+ make_init_from_struct ( input . ident , struct_data ) . unwrap_or_else ( |e| e. to_compile_error ( ) )
95
+ }
97
96
syn:: Data :: Enum ( enum_data) => Error :: new (
98
97
enum_data. enum_token . span ,
99
98
"[IntoEvent] `derive(IntoEvent)` cannot be applied to Enum." ,
@@ -108,3 +107,126 @@ pub fn derive_into_event(input: DeriveInput) -> TokenStream {
108
107
. into ( ) ,
109
108
}
110
109
}
110
+
111
+ /// derive `IntoEvent` from a derive input. The input needs to be a struct.
112
+ pub fn derive_into_event ( input : DeriveInput ) -> TokenStream {
113
+ derive_into_event_impl ( input) . into ( )
114
+ }
115
+
116
+ #[ cfg( test) ]
117
+ mod tests {
118
+ use super :: * ;
119
+ use proc_macro2:: TokenStream ;
120
+ use syn:: parse_quote;
121
+
122
+ fn expect_compile_error ( ts : TokenStream , msg : & str ) {
123
+ assert ! (
124
+ ts. to_string( ) . starts_with( "compile_error ! {" ) ,
125
+ "Code does not raise compile error: `{}`" ,
126
+ ts. to_string( )
127
+ ) ;
128
+
129
+ assert ! (
130
+ ts. to_string( ) . contains( msg) ,
131
+ "Error does not have expected message \" {}\" : `{}`" ,
132
+ msg,
133
+ ts. to_string( )
134
+ ) ;
135
+ }
136
+
137
+ #[ test]
138
+ fn test_doc_example ( ) {
139
+ let input: DeriveInput = parse_quote ! {
140
+ struct StructName {
141
+ field_name_1: field_type_1,
142
+ #[ use_to_string]
143
+ field_name_2: field_type_2,
144
+ #[ to_string_fn( cast_fn_3) ]
145
+ field_name_3: field_type_3,
146
+ }
147
+ } ;
148
+ let result_implement = derive_into_event_impl ( input) ;
149
+ let expected: TokenStream = parse_quote ! {
150
+ impl Into <cosmwasm_std:: Event > for StructName {
151
+ fn into( self ) -> cosmwasm_std:: Event {
152
+ cosmwasm_std:: Event :: new( "struct_name" )
153
+ . add_attribute( stringify!( field_name_1) , self . field_name_1)
154
+ . add_attribute( stringify!( field_name_2) , self . field_name_2. to_string( ) )
155
+ . add_attribute( stringify!( field_name_3) , cast_fn_3 ( self . field_name_3) )
156
+ }
157
+ }
158
+ } ;
159
+ assert_eq ! ( expected. to_string( ) , result_implement. to_string( ) )
160
+ }
161
+
162
+ #[ test]
163
+ fn test_error_multiple_to_string_functions ( ) {
164
+ let input: DeriveInput = parse_quote ! {
165
+ struct StructName {
166
+ #[ to_string_fn( cast_fn_1) ]
167
+ #[ to_string_fn( cast_fn_1) ]
168
+ field_name_1: field_type_1,
169
+ }
170
+ } ;
171
+ let result_implement = derive_into_event_impl ( input) ;
172
+ expect_compile_error (
173
+ result_implement,
174
+ "[IntoEvent] Only one or zero `to_string_fn`" ,
175
+ ) ;
176
+ }
177
+
178
+ #[ test]
179
+ fn test_error_use_to_string_has_value ( ) {
180
+ let input: DeriveInput = parse_quote ! {
181
+ struct StructName {
182
+ #[ use_to_string( foo) ]
183
+ field_name_1: field_type_1,
184
+ }
185
+ } ;
186
+ let result_implement = derive_into_event_impl ( input) ;
187
+ expect_compile_error (
188
+ result_implement,
189
+ "[IntoEvent] An attribute `use_to_string` has some value" ,
190
+ ) ;
191
+ }
192
+
193
+ #[ test]
194
+ fn test_error_both_two_attributes_is_used ( ) {
195
+ let input: DeriveInput = parse_quote ! {
196
+ struct StructName {
197
+ #[ use_to_string]
198
+ #[ to_string_fn( cast_fn_1) ]
199
+ field_name_1: field_type_1,
200
+ }
201
+ } ;
202
+ let result_implement = derive_into_event_impl ( input) ;
203
+ expect_compile_error (
204
+ result_implement,
205
+ "[IntoEvent] Both `use_to_string` and `to_string_fn`" ,
206
+ ) ;
207
+ }
208
+
209
+ #[ test]
210
+ fn test_error_derive_enum ( ) {
211
+ let input: DeriveInput = parse_quote ! {
212
+ enum Enum { }
213
+ } ;
214
+ let result_implement = derive_into_event_impl ( input) ;
215
+ expect_compile_error (
216
+ result_implement,
217
+ "[IntoEvent] `derive(IntoEvent)` cannot be applied to Enum" ,
218
+ ) ;
219
+ }
220
+
221
+ #[ test]
222
+ fn test_error_derive_union ( ) {
223
+ let input: DeriveInput = parse_quote ! {
224
+ union Union { }
225
+ } ;
226
+ let result_implement = derive_into_event_impl ( input) ;
227
+ expect_compile_error (
228
+ result_implement,
229
+ "[IntoEvent] `derive(IntoEvent)` cannot be applied to Union" ,
230
+ ) ;
231
+ }
232
+ }
0 commit comments