(input: Struct)
| 29 | } |
| 30 | |
| 31 | fn impl_struct(input: Struct) -> TokenStream { |
| 32 | let ty = call_site_ident(&input.ident); |
| 33 | let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); |
| 34 | let mut error_inferred_bounds = InferredBounds::new(); |
| 35 | |
| 36 | let source_body = if let Some(transparent_attr) = &input.attrs.transparent { |
| 37 | let only_field = &input.fields[0]; |
| 38 | if only_field.contains_generic { |
| 39 | error_inferred_bounds.insert(only_field.ty, quote!(::thiserror::#private::Error)); |
| 40 | } |
| 41 | let member = &only_field.member; |
| 42 | Some(quote_spanned! {transparent_attr.span=> |
| 43 | ::thiserror::#private::Error::source(self.#member.as_dyn_error()) |
| 44 | }) |
| 45 | } else if let Some(source_field) = input.source_field() { |
| 46 | let source = &source_field.member; |
| 47 | if source_field.contains_generic { |
| 48 | let ty = unoptional_type(source_field.ty); |
| 49 | error_inferred_bounds.insert(ty, quote!(::thiserror::#private::Error + 'static)); |
| 50 | } |
| 51 | let asref = if type_is_option(source_field.ty) { |
| 52 | Some(quote_spanned!(source.span()=> .as_ref()?)) |
| 53 | } else { |
| 54 | None |
| 55 | }; |
| 56 | let dyn_error = quote_spanned! {source_field.source_span()=> |
| 57 | self.#source #asref.as_dyn_error() |
| 58 | }; |
| 59 | Some(quote! { |
| 60 | ::core::option::Option::Some(#dyn_error) |
| 61 | }) |
| 62 | } else { |
| 63 | None |
| 64 | }; |
| 65 | let source_method = source_body.map(|body| { |
| 66 | quote! { |
| 67 | fn source(&self) -> ::core::option::Option<&(dyn ::thiserror::#private::Error + 'static)> { |
| 68 | use ::thiserror::#private::AsDynError as _; |
| 69 | #body |
| 70 | } |
| 71 | } |
| 72 | }); |
| 73 | |
| 74 | let provide_method = input.backtrace_field().map(|backtrace_field| { |
| 75 | let request = quote!(request); |
| 76 | let backtrace = &backtrace_field.member; |
| 77 | let body = if let Some(source_field) = input.source_field() { |
| 78 | let source = &source_field.member; |
| 79 | let source_provide = if type_is_option(source_field.ty) { |
| 80 | quote_spanned! {source.span()=> |
| 81 | if let ::core::option::Option::Some(source) = &self.#source { |
| 82 | source.thiserror_provide(#request); |
| 83 | } |
| 84 | } |
| 85 | } else { |
| 86 | quote_spanned! {source.span()=> |
| 87 | self.#source.thiserror_provide(#request); |
| 88 | } |
no test coverage detected