@@ -2,6 +2,7 @@ use std::borrow::Cow;
2
2
use std:: collections:: { HashMap , HashSet } ;
3
3
use std:: fmt:: Display ;
4
4
use std:: iter;
5
+ use std:: ops:: Range ;
5
6
6
7
use collection_literals:: hash;
7
8
use interpolator:: { format, Formattable } ;
@@ -10,8 +11,8 @@ use proc_macro2::{Literal, Span, TokenStream};
10
11
use proc_macro_utils:: { TokenParser , TokenStream2Ext } ;
11
12
use quote:: { format_ident, ToTokens } ;
12
13
use quote_use:: quote_use as quote;
13
- use syn:: { spanned:: Spanned , Visibility } ;
14
- use syn:: { DataStruct , DeriveInput , Field , Fields , Generics , Ident , LitStr , Type } ;
14
+ use syn:: spanned:: Spanned ;
15
+ use syn:: { DataStruct , DeriveInput , Field , Fields , Generics , Ident , LitStr , Type , Visibility } ;
15
16
16
17
const ATTRIBUTE_IDENT : & str = "attribute" ;
17
18
@@ -170,8 +171,13 @@ struct StructAttrs {
170
171
}
171
172
172
173
impl StructAttrs {
173
- fn from_attrs ( attrs : impl IntoIterator < Item = syn:: Attribute > ) -> Result < Self > {
174
- const VALID_FORMAT : & str = r#"expected `#[attribute(ident=attribute_name, aliases=[alias1, alias2], error="..", error(unknown_field="..", unknown_field_single="..", unknown_field_empty="..", duplicate_field="..", missing_field="..", field_help=".."))]`"# ;
174
+ fn from_attrs (
175
+ struct_ident : & Ident ,
176
+ attrs : impl IntoIterator < Item = syn:: Attribute > ,
177
+ ) -> Result < Self > {
178
+ const VALID_FORMAT : & str = r#"expected `#[attribute(ident=attribute_name/!ident, aliases=[alias1, alias2], error="..", error(unknown_field="..", unknown_field_single="..", unknown_field_empty="..", duplicate_field="..", missing_field="..", field_help=".."))]`"# ;
179
+
180
+ let mut ident_span: Option < Range < Span > > = None ;
175
181
let mut ident: Option < Ident > = None ;
176
182
let mut aliases: Vec < String > = vec ! [ ] ;
177
183
let mut error = StructError :: Specific ( Default :: default ( ) ) ;
@@ -188,105 +194,152 @@ impl StructAttrs {
188
194
. clone ( )
189
195
. parser ( ) ;
190
196
while !parser. is_empty ( ) {
191
- let field = parser
192
- . next_ident ( )
193
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
194
- match field. to_string ( ) . as_str ( ) {
195
- "ident" => {
196
- parser
197
- . next_tt_eq ( )
198
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
199
- ident = Some (
200
- parser
201
- . next_ident ( )
202
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?,
203
- )
204
- }
205
- "aliases" => {
206
- parser
207
- . next_tt_eq ( )
208
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
209
- let mut parser = parser
210
- . next_bracketed ( )
211
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?
212
- . stream ( )
213
- . parser ( ) ;
214
- aliases. extend ( iter:: from_fn ( || {
215
- _ = parser. next_tt_comma ( ) ;
216
- parser. next_ident ( ) . map ( |t| t. to_string ( ) )
217
- } ) ) ;
218
- if !parser. is_empty ( ) {
219
- bail ! ( "{VALID_FORMAT}" )
197
+ eprintln ! ( "{}" , parser. to_token_stream( ) ) ;
198
+ if let Some ( not) = parser. next_tt_not ( ) {
199
+ if let Some ( kw) = parser. next_keyword ( "ident" ) {
200
+ if let Some ( ident_span) = ident_span {
201
+ bail ! (
202
+ error_message!( ident_span, "ident is specified twice" )
203
+ + error_message!(
204
+ not. span( ) ..kw. span( ) ,
205
+ "ident was already specified"
206
+ )
207
+ )
208
+ } else {
209
+ ident_span = Some ( not. span ( ) ..kw. span ( ) ) ;
220
210
}
221
211
}
222
- "error" => {
223
- if parser. next_tt_eq ( ) . is_some ( ) {
224
- error = StructError :: Generic (
225
- FormatString :: parse ( parser)
212
+ } else {
213
+ let field = parser
214
+ . next_ident ( )
215
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
216
+ match field. to_string ( ) . as_str ( ) {
217
+ "ident" => {
218
+ parser
219
+ . next_tt_eq ( )
220
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
221
+ ident = Some (
222
+ parser
223
+ . next_ident ( )
226
224
. ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?,
227
225
) ;
228
- } else {
229
- let parser = & mut parser
230
- . next_parenthesized ( )
226
+ if let Some ( ident_span) = ident_span {
227
+ bail ! (
228
+ error_message!( ident_span, "ident is specified twice" )
229
+ + error_message!(
230
+ field. span( ) ..ident. unwrap( ) . span( ) ,
231
+ "ident was already specified"
232
+ )
233
+ )
234
+ }
235
+ }
236
+ "aliases" => {
237
+ parser
238
+ . next_tt_eq ( )
239
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
240
+ let mut parser = parser
241
+ . next_bracketed ( )
231
242
. ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?
232
243
. stream ( )
233
244
. parser ( ) ;
234
- let error = if let StructError :: Specific ( error) = & mut error {
235
- error
245
+ aliases. extend ( iter:: from_fn ( || {
246
+ _ = parser. next_tt_comma ( ) ;
247
+ parser. next_ident ( ) . map ( |t| t. to_string ( ) )
248
+ } ) ) ;
249
+ if !parser. is_empty ( ) {
250
+ bail ! ( "{VALID_FORMAT}" )
251
+ }
252
+ }
253
+ "error" => {
254
+ if parser. next_tt_eq ( ) . is_some ( ) {
255
+ error = StructError :: Generic (
256
+ FormatString :: parse ( parser)
257
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?,
258
+ ) ;
236
259
} else {
237
- error = StructError :: Specific ( Default :: default ( ) ) ;
238
- if let StructError :: Specific ( error) = & mut error {
260
+ let parser = & mut parser
261
+ . next_parenthesized ( )
262
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?
263
+ . stream ( )
264
+ . parser ( ) ;
265
+ let error = if let StructError :: Specific ( error) = & mut error {
239
266
error
240
267
} else {
241
- unreachable ! ( )
242
- }
243
- } ;
244
- while !parser. is_empty ( ) {
245
- let field = parser
246
- . next_ident ( )
247
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
248
- let mut string = |f : & mut _ | -> Result < ( ) > {
249
- parser
250
- . next_tt_eq ( )
251
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
252
- * f = FormatString :: parse ( parser)
253
- . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
254
- Ok ( ( ) )
255
- } ;
256
- match field. to_string ( ) . as_str ( ) {
257
- "unknown_field" => string ( & mut error. unknown_field ) ,
258
- "unknown_field_empty" => string ( & mut error. unknown_field_empty ) ,
259
- "unknown_field_single" => {
260
- string ( & mut error. unknown_field_single )
268
+ error = StructError :: Specific ( Default :: default ( ) ) ;
269
+ if let StructError :: Specific ( error) = & mut error {
270
+ error
271
+ } else {
272
+ unreachable ! ( )
261
273
}
262
- "duplicate_field" => string ( & mut error. duplicate_field ) ,
263
- "missing_field" => string ( & mut error. missing_field ) ,
264
- "field_help" => string ( & mut error. field_help ) ,
265
- "conflict" => string ( & mut error. conflict ) ,
266
- _ => bail ! ( field, "{VALID_FORMAT}" ) ,
267
- } ?;
268
- _ = parser. next_tt_comma ( ) ;
274
+ } ;
275
+ while !parser. is_empty ( ) {
276
+ let field = parser
277
+ . next_ident ( )
278
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
279
+ let mut string = |f : & mut _ | -> Result < ( ) > {
280
+ parser
281
+ . next_tt_eq ( )
282
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
283
+ * f = FormatString :: parse ( parser)
284
+ . ok_or_else ( || ErrorMessage :: call_site ( VALID_FORMAT ) ) ?;
285
+ Ok ( ( ) )
286
+ } ;
287
+ match field. to_string ( ) . as_str ( ) {
288
+ "unknown_field" => string ( & mut error. unknown_field ) ,
289
+ "unknown_field_empty" => {
290
+ string ( & mut error. unknown_field_empty )
291
+ }
292
+ "unknown_field_single" => {
293
+ string ( & mut error. unknown_field_single )
294
+ }
295
+ "duplicate_field" => string ( & mut error. duplicate_field ) ,
296
+ "missing_field" => string ( & mut error. missing_field ) ,
297
+ "field_help" => string ( & mut error. field_help ) ,
298
+ "conflict" => string ( & mut error. conflict ) ,
299
+ _ => bail ! ( field, "{VALID_FORMAT}" ) ,
300
+ } ?;
301
+ _ = parser. next_tt_comma ( ) ;
302
+ }
269
303
}
270
304
}
305
+ // "duplicate" => {
306
+ // parser.next_eq() .ok_or_else(||
307
+ // ErrorMessage::call_site(VALID_FORMAT))?; let strategy
308
+ // = parser.next_ident() .ok_or_else(||
309
+ // ErrorMessage::call_site(VALID_FORMAT))?; duplicate =
310
+ // match strategy.to_string().as_str() {
311
+ // "AggregateOrError" => DuplicateStrategy::AggregateOrError,
312
+ // "Error" => DuplicateStrategy::Error,
313
+ // "AggregateOrOverride" => DuplicateStrategy::AggregateOrOverride,
314
+ // "Override" => DuplicateStrategy::Override,
315
+ // _ => abort!(strategy, VALID_FORMAT),
316
+ // }
317
+ // }
318
+ _ => bail ! ( field, "{VALID_FORMAT}" ) ,
271
319
}
272
- // "duplicate" => {
273
- // parser.next_eq() .ok_or_else(||
274
- // ErrorMessage::call_site(VALID_FORMAT))?; let strategy
275
- // = parser.next_ident() .ok_or_else(||
276
- // ErrorMessage::call_site(VALID_FORMAT))?; duplicate =
277
- // match strategy.to_string().as_str() {
278
- // "AggregateOrError" => DuplicateStrategy::AggregateOrError,
279
- // "Error" => DuplicateStrategy::Error,
280
- // "AggregateOrOverride" => DuplicateStrategy::AggregateOrOverride,
281
- // "Override" => DuplicateStrategy::Override,
282
- // _ => abort!(strategy, VALID_FORMAT),
283
- // }
284
- // }
285
- _ => bail ! ( field, "{VALID_FORMAT}" ) ,
286
320
}
287
321
_ = parser. next_tt_comma ( ) ;
288
322
}
289
323
}
324
+
325
+ if ident_span. is_none ( ) && ident. is_none ( ) {
326
+ let ident_string = struct_ident. to_string ( ) ;
327
+ let mut out = String :: with_capacity ( ident_string. len ( ) ) ;
328
+ let mut ident_string = ident_string. chars ( ) ;
329
+
330
+ out. extend ( ident_string. next ( ) . into_iter ( ) . flat_map ( char:: to_lowercase) ) ;
331
+ for c in ident_string {
332
+ if c. is_uppercase ( ) {
333
+ out. push ( '_' ) ;
334
+ out. extend ( c. to_lowercase ( ) ) ;
335
+ } else {
336
+ out. push ( c) ;
337
+ }
338
+ }
339
+
340
+ ident = Some ( Ident :: new ( & out, struct_ident. span ( ) ) ) ;
341
+ }
342
+
290
343
Ok ( Self {
291
344
ident,
292
345
aliases,
@@ -790,11 +843,11 @@ pub fn from_attr_derive(
790
843
mut aliases,
791
844
error : ref struct_error,
792
845
// duplicate,
793
- } = StructAttrs :: from_attrs ( attrs) ?;
846
+ } = StructAttrs :: from_attrs ( & ident , attrs) ?;
794
847
795
848
let ( impl_generics, ty_generics, where_clause) = generics. split_for_impl ( ) ;
796
849
797
- if let Some ( attribute_ident) = attribute_ident. clone ( ) {
850
+ if let Some ( ref attribute_ident) = attribute_ident {
798
851
aliases. insert ( 0 , attribute_ident. to_string ( ) ) ;
799
852
}
800
853
@@ -815,7 +868,7 @@ pub fn from_attr_derive(
815
868
fields : fields @ ( Fields :: Named ( _) | Fields :: Unnamed ( _) ) ,
816
869
..
817
870
} ) => AttrField :: parse_fields ( fields, struct_error, attribute_ident) ?,
818
- _ => bail ! ( "only works on structs with named fields" ) ,
871
+ _ => bail ! ( "only works on structs with fields" ) ,
819
872
} ;
820
873
821
874
let conflicts = conflicts. to_tokens ( struct_error) ?;
0 commit comments