@@ -12,7 +12,8 @@ use proc_macro2::{Ident, Span};
1212use quote:: { quote, ToTokens } ;
1313use std:: default:: Default ;
1414use syn:: {
15- parse_macro_input, Expr , GenericParam , Generics , Item , ItemEnum , ItemStruct , LitStr , TypeParam ,
15+ parse_macro_input, parse_quote, Expr , GenericParam , Generics , Item , ItemEnum , ItemStruct ,
16+ LitStr , TypeParam , WhereClause , WherePredicate ,
1617} ;
1718
1819#[ proc_macro_attribute]
@@ -167,25 +168,15 @@ fn generate_parser(
167168 object : impl ToTokens ,
168169 content : impl ToTokens ,
169170) -> TokenStream {
170- let ( impl_generics, extra_where_predicates) = parser_generics ( generics. clone ( ) ) ;
171+ let merged_generics = parser_generics ( generics. clone ( ) ) ;
172+ let ( impl_generics, _, where_statement) = merged_generics. split_for_impl ( ) ;
173+ let ( _, type_generics, _) = generics. split_for_impl ( ) ;
171174
172175 let tokens = quote ! {
173176 #object
174177
175- impl #impl_generics nom_parse_trait:: ParseFrom <I , E > for #name #generics
176- where
177- #( #extra_where_predicates, ) *
178- E : nom:: error:: ParseError <I >,
179- I : Clone ,
180- I : nom:: Slice <std:: ops:: RangeTo <usize >> + nom:: Slice <std:: ops:: RangeFrom <usize >> + nom:: Slice <std:: ops:: Range <usize >>,
181- I : nom:: InputTake + nom:: InputLength + nom:: Offset + nom:: AsBytes ,
182- I : nom:: InputIter ,
183- <I as nom:: InputIter >:: Item : nom:: AsChar + Copy ,
184- <I as nom:: InputIter >:: IterElem : Clone ,
185- I : nom:: InputTakeAtPosition ,
186- <I as nom:: InputTakeAtPosition >:: Item : nom:: AsChar + Copy ,
187- I : for <' a> nom:: Compare <& ' a [ u8 ] >,
188- I : nom:: Compare <& ' static str >,
178+ impl #impl_generics nom_parse_trait:: ParseFrom <I , E > for #name #type_generics
179+ #where_statement
189180 {
190181 fn parse( input: I ) -> nom:: IResult <I , Self , E > {
191182 use nom:: * ;
@@ -198,7 +189,7 @@ fn generate_parser(
198189 tokens. into ( )
199190}
200191
201- fn parser_generics ( mut generics : Generics ) -> ( Generics , Vec < proc_macro2 :: TokenStream > ) {
192+ fn parser_generics ( mut generics : Generics ) -> Generics {
202193 // If there are no generics, start a new one
203194 if generics. params . is_empty ( ) {
204195 generics = Generics :: default ( ) ;
@@ -207,12 +198,12 @@ fn parser_generics(mut generics: Generics) -> (Generics, Vec<proc_macro2::TokenS
207198 }
208199
209200 // Generate some extra where predicates for the generics
210- let extra_where_predicates : Vec < _ > = generics
201+ let extra_parse_from_traits : Vec < WherePredicate > = generics
211202 . params
212203 . iter ( )
213204 . flat_map ( |param| {
214205 if let GenericParam :: Type ( TypeParam { ident, .. } ) = param {
215- Some ( quote ! { #ident: nom_parse_trait:: ParseFrom <I , E > } )
206+ Some ( parse_quote ! { #ident: nom_parse_trait:: ParseFrom <I , E > } )
216207 } else {
217208 None
218209 }
@@ -233,5 +224,54 @@ fn parser_generics(mut generics: Generics) -> (Generics, Vec<proc_macro2::TokenS
233224 Span :: call_site ( ) ,
234225 ) ) ) ) ;
235226
236- ( generics, extra_where_predicates)
227+ if generics. where_clause . is_none ( ) {
228+ generics. where_clause = Some ( WhereClause {
229+ where_token : Default :: default ( ) ,
230+ predicates : Default :: default ( ) ,
231+ } ) ;
232+ }
233+
234+ let where_clause = generics. where_clause . as_mut ( ) . unwrap ( ) ;
235+ for extra_parse_from_traits in extra_parse_from_traits {
236+ where_clause. predicates . push ( extra_parse_from_traits) ;
237+ }
238+
239+ where_clause
240+ . predicates
241+ . push ( parse_quote ! { I : nom:: InputTake + nom:: InputLength + nom:: Offset + nom:: AsBytes } ) ;
242+
243+ where_clause
244+ . predicates
245+ . push ( parse_quote ! { E : nom:: error:: ParseError <I > } ) ;
246+ where_clause. predicates . push ( parse_quote ! { I : Clone } ) ;
247+ where_clause. predicates . push ( parse_quote ! { I : nom:: Slice <std:: ops:: RangeTo <usize >> + nom:: Slice <std:: ops:: RangeFrom <usize >> + nom:: Slice <std:: ops:: Range <usize >> } ) ;
248+ where_clause
249+ . predicates
250+ . push ( parse_quote ! { I : nom:: InputTake + nom:: InputLength + nom:: Offset + nom:: AsBytes } ) ;
251+ where_clause
252+ . predicates
253+ . push ( parse_quote ! { I : nom:: InputIter } ) ;
254+ where_clause
255+ . predicates
256+ . push ( parse_quote ! { <I as nom:: InputIter >:: Item : nom:: AsChar + Copy } ) ;
257+ where_clause
258+ . predicates
259+ . push ( parse_quote ! { <I as nom:: InputIter >:: IterElem : Clone } ) ;
260+ where_clause
261+ . predicates
262+ . push ( parse_quote ! { I : nom:: InputTakeAtPosition } ) ;
263+ where_clause
264+ . predicates
265+ . push ( parse_quote ! { <I as nom:: InputTakeAtPosition >:: Item : nom:: AsChar + Copy } ) ;
266+ where_clause
267+ . predicates
268+ . push ( parse_quote ! { I : for <' a> nom:: Compare <& ' a [ u8 ] > } ) ;
269+ where_clause
270+ . predicates
271+ . push ( parse_quote ! { I : nom:: Compare <& ' static str > } ) ;
272+ where_clause
273+ . predicates
274+ . push ( parse_quote ! { for <' a> & ' a str : nom:: FindToken <<I as nom:: InputIter >:: Item > } ) ;
275+
276+ generics
237277}
0 commit comments