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