@@ -14,6 +14,12 @@ pub(crate) enum FieldSelector {
14
14
Index ( usize ) ,
15
15
}
16
16
17
+ impl Default for FieldSelector {
18
+ fn default ( ) -> Self {
19
+ Self :: Index ( 0 )
20
+ }
21
+ }
22
+
17
23
#[ derive( Clone , Default ) ]
18
24
pub ( crate ) struct VariantConfig {
19
25
discriminant : Option < DiscriminantConfig > ,
@@ -60,42 +66,41 @@ impl VariantConfig {
60
66
Ok ( this)
61
67
}
62
68
63
- pub ( crate ) fn position_of_selected_field (
69
+ pub ( crate ) fn selected_field < ' a > (
64
70
& self ,
65
- fields : & syn:: Fields ,
66
- ) -> Result < usize , syn:: Error > {
67
- if let Some ( selector) = & self . field {
68
- match selector {
69
- FieldSelector :: Name ( name) => {
70
- let position = fields
71
- . iter ( )
72
- . position ( |field| {
73
- field
74
- . ident
75
- . as_ref ( )
76
- . map ( |ident| ident == name)
77
- . unwrap_or ( false )
78
- } )
79
- . expect ( "field name should have been rejected" ) ;
80
-
81
- return Ok ( position) ;
82
- }
83
- FieldSelector :: Index ( index) => {
84
- if * index >= fields. len ( ) {
85
- return Err ( syn:: Error :: new_spanned ( fields, "field index out of bounds" ) ) ;
86
- }
87
- return Ok ( * index) ;
88
- }
71
+ fields : & ' a syn:: Fields ,
72
+ ) -> Result < Option < ( & ' a syn:: Field , usize ) > , syn:: Error > {
73
+ let default_field_selector = FieldSelector :: default ( ) ;
74
+ let field_selector = self . field . as_ref ( ) . unwrap_or ( & default_field_selector) ;
75
+
76
+ if fields. is_empty ( ) {
77
+ return Ok ( None ) ;
78
+ }
79
+
80
+ match field_selector {
81
+ FieldSelector :: Name ( name) => {
82
+ let ( index, field) = fields
83
+ . iter ( )
84
+ . enumerate ( )
85
+ . find ( |( _, field) | {
86
+ field
87
+ . ident
88
+ . as_ref ( )
89
+ . map ( |ident| ident == name)
90
+ . unwrap_or ( false )
91
+ } )
92
+ . expect ( "field name should have been rejected" ) ;
93
+
94
+ Ok ( Some ( ( field, index) ) )
95
+ }
96
+ FieldSelector :: Index ( index) => {
97
+ let field = fields
98
+ . iter ( )
99
+ . nth ( * index)
100
+ . expect ( "field index should have been rejected" ) ;
101
+
102
+ Ok ( Some ( ( field, * index) ) )
89
103
}
90
- } ;
91
-
92
- match fields. len ( ) {
93
- 0 => Err ( syn:: Error :: new_spanned ( fields, "no fields" ) ) ,
94
- 1 => Ok ( 0 ) ,
95
- _ => Err ( syn:: Error :: new_spanned (
96
- fields,
97
- "multiple fields, please disambiguate via helper attribute" ,
98
- ) ) ,
99
104
}
100
105
}
101
106
@@ -106,4 +111,9 @@ impl VariantConfig {
106
111
pub ( crate ) fn exclude ( & self ) -> Option < & ExcludeConfig > {
107
112
self . exclude . as_ref ( )
108
113
}
114
+
115
+ #[ allow( dead_code) ]
116
+ pub ( crate ) fn field ( & self ) -> Option < & FieldSelector > {
117
+ self . field . as_ref ( )
118
+ }
109
119
}
0 commit comments