1- use  darling:: FromAttributes ; 
21use  proc_macro:: TokenStream ; 
32use  proc_macro2:: Span ; 
43use  quote:: { quote,  ToTokens } ; 
@@ -164,12 +163,12 @@ fn add_meta_field(fields: &mut Fields) {
164163pub  fn  derive_stack_error ( input :  TokenStream )  -> TokenStream  { 
165164    let  input = parse_macro_input ! ( input as  syn:: DeriveInput ) ; 
166165    match  derive_error_inner ( input)  { 
167-         Err ( tokens )  => tokens . write_errors ( ) . into ( ) , 
166+         Err ( err )  => err . to_compile_error ( ) . into ( ) , 
168167        Ok ( tokens)  => tokens. into ( ) , 
169168    } 
170169} 
171170
172- fn  derive_error_inner ( input :  DeriveInput )  -> Result < proc_macro2:: TokenStream ,  darling :: Error >  { 
171+ fn  derive_error_inner ( input :  DeriveInput )  -> Result < proc_macro2:: TokenStream ,  syn :: Error >  { 
173172    match  & input. data  { 
174173        syn:: Data :: Enum ( item)  => { 
175174            let  args = EnumAttrArgs :: from_attributes ( & input. attrs ) ?; 
@@ -191,8 +190,7 @@ fn derive_error_inner(input: DeriveInput) -> Result<proc_macro2::TokenStream, da
191190        _ => Err ( err ( 
192191            & input, 
193192            "#[derive(StackError)] only supports enums or structs" , 
194-         ) 
195-         . into ( ) ) , 
193+         ) ) , 
196194    } 
197195} 
198196
@@ -222,24 +220,61 @@ enum SourceKind {
222220    Std , 
223221} 
224222
225- #[ derive( Default ,  Clone ,  Copy ,  darling:: FromMeta ) ]  
226- #[ darling( default ,  derive_syn_parse) ]  
223+ #[ derive( Default ,  Clone ,  Copy ) ]  
227224struct  StackErrAttrArgs  { 
228225    add_meta :  bool , 
229226    derive :  bool , 
230227    from_sources :  bool , 
231228    std_sources :  bool , 
232229} 
233230
234- #[ derive( Default ,  Clone ,  Copy ,  FromAttributes ) ]  
235- #[ darling( default ,  attributes( error,  stackerr) ) ]  
231+ impl  syn:: parse:: Parse  for  StackErrAttrArgs  { 
232+     fn  parse ( input :  syn:: parse:: ParseStream < ' _ > )  -> syn:: Result < Self >  { 
233+         let  mut  out = Self :: default ( ) ; 
234+         while  !input. is_empty ( )  { 
235+             let  ident:  Ident  = input. parse ( ) ?; 
236+             match  ident. to_string ( ) . as_str ( )  { 
237+                 "add_meta"  => out. add_meta  = true , 
238+                 "derive"  => out. derive  = true , 
239+                 "from_sources"  => out. from_sources  = true , 
240+                 "std_sources"  => out. std_sources  = true , 
241+                 other => Err ( err ( 
242+                     ident, 
243+                     format ! ( "unknown stack_error option `{}`" ,  other) , 
244+                 ) ) ?, 
245+             } 
246+             if  input. peek ( syn:: Token ![ , ] )  { 
247+                 let  _ = input. parse :: < syn:: Token ![ , ] > ( ) ?; 
248+             } 
249+         } 
250+         Ok ( out) 
251+     } 
252+ } 
253+ 
254+ #[ derive( Default ,  Clone ,  Copy ) ]  
236255struct  EnumAttrArgs  { 
237256    from_sources :  bool , 
238257    std_sources :  bool , 
239258} 
240259
241- #[ derive( Default ,  Clone ,  Copy ,  FromAttributes ) ]  
242- #[ darling( default ,  attributes( error) ) ]  
260+ impl  EnumAttrArgs  { 
261+     fn  from_attributes ( attrs :  & [ Attribute ] )  -> Result < Self ,  syn:: Error >  { 
262+         let  mut  out = Self :: default ( ) ; 
263+         for  ident in  parse_error_attr_as_idents ( attrs) ? { 
264+             match  ident. to_string ( ) . as_str ( )  { 
265+                 "from_sources"  => out. from_sources  = true , 
266+                 "std_sources"  => out. std_sources  = true , 
267+                 _ => Err ( err ( 
268+                     ident, 
269+                     "Invalid argument for the `error` attribute on fields" , 
270+                 ) ) ?, 
271+             } 
272+         } 
273+         Ok ( out) 
274+     } 
275+ } 
276+ 
277+ #[ derive( Default ,  Clone ,  Copy ) ]  
243278struct  FieldAttrArgs  { 
244279    source :  bool , 
245280    from :  bool , 
@@ -248,6 +283,26 @@ struct FieldAttrArgs {
248283    meta :  bool , 
249284} 
250285
286+ impl  FieldAttrArgs  { 
287+     fn  from_attributes ( attrs :  & [ Attribute ] )  -> Result < Self ,  syn:: Error >  { 
288+         let  mut  out = Self :: default ( ) ; 
289+         for  ident in  parse_error_attr_as_idents ( attrs) ? { 
290+             match  ident. to_string ( ) . as_str ( )  { 
291+                 "source"  => out. source  = true , 
292+                 "from"  => out. from  = true , 
293+                 "std_err"  => out. std_err  = true , 
294+                 "stack_err"  => out. stack_err  = true , 
295+                 "meta"  => out. meta  = true , 
296+                 _ => Err ( err ( 
297+                     ident, 
298+                     "Invalid argument for the `error` attribute on fields" , 
299+                 ) ) ?, 
300+             } 
301+         } 
302+         Ok ( out) 
303+     } 
304+ } 
305+ 
251306#[ derive( Debug ,  Clone ,  Copy ) ]  
252307enum  VariantIdent < ' a >  { 
253308    Struct ( & ' a  Ident ) , 
@@ -888,8 +943,8 @@ impl DisplayArgs {
888943        } 
889944
890945        // #[error("...", args...)] 
891-         let  mut  it  = args. into_iter ( ) ; 
892-         let  first = it . next ( ) . unwrap ( ) ; 
946+         let  mut  args  = args. into_iter ( ) ; 
947+         let  first = args . next ( ) . unwrap ( ) ; 
893948        let  fmt_lit = match  first { 
894949            Expr :: Lit ( syn:: ExprLit  {  lit :  syn:: Lit :: Str ( s) ,  .. } )  => s, 
895950            other => return  Err ( err ( 
@@ -898,7 +953,7 @@ impl DisplayArgs {
898953            ) ) 
899954        } ; 
900955
901-         let  rest:  Vec < Expr >  = it . collect ( ) ; 
956+         let  rest:  Vec < Expr >  = args . collect ( ) ; 
902957        Ok ( DisplayArgs :: Format ( 
903958            quote !  {  write!( f,  #fmt_lit #( ,  #rest) *  )  } , 
904959        ) ) 
@@ -908,3 +963,16 @@ impl DisplayArgs {
908963fn  err ( ident :  impl  ToTokens ,  err :  impl  ToString )  -> syn:: Error  { 
909964    syn:: Error :: new_spanned ( ident,  err. to_string ( ) ) 
910965} 
966+ 
967+ fn  parse_error_attr_as_idents ( attrs :  & [ Attribute ] )  -> Result < Vec < Ident > ,  syn:: Error >  { 
968+     let  mut  out = vec ! [ ] ; 
969+     for  attr in  attrs. iter ( ) . filter ( |a| a. path ( ) . is_ident ( "error" ) )  { 
970+         let  idents = attr. parse_args_with ( |input :  syn:: parse:: ParseStream < ' _ > | { 
971+             let  list:  Punctuated < Ident ,  syn:: Token ![ , ] >  =
972+                 Punctuated :: < Ident ,  syn:: Token ![ , ] > :: parse_terminated ( input) ?; 
973+             Ok ( list. into_iter ( ) ) 
974+         } ) ?; 
975+         out. extend ( idents) ; 
976+     } 
977+     Ok ( out) 
978+ } 
0 commit comments