From 60c6ce824c1b19adc86d893053010e1de52c3265 Mon Sep 17 00:00:00 2001 From: HampusM Date: Fri, 22 Dec 2023 12:33:35 +0100 Subject: feat: add support for async constructors --- macros/src/injectable/implementation.rs | 34 ++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'macros/src/injectable') diff --git a/macros/src/injectable/implementation.rs b/macros/src/injectable/implementation.rs index e2bcd3e..a98d1ce 100644 --- a/macros/src/injectable/implementation.rs +++ b/macros/src/injectable/implementation.rs @@ -83,7 +83,7 @@ impl InjectableImpl }) } - pub fn validate(&self) -> Result<(), InjectableImplError> + pub fn validate(&self, is_async: bool) -> Result<(), InjectableImplError> { if matches!(self.constructor_method.sig.output, ReturnType::Default) { return Err(InjectableImplError::InvalidConstructorMethodReturnType { @@ -127,10 +127,14 @@ impl InjectableImpl }); } - if let Some(asyncness) = self.constructor_method.sig.asyncness { - return Err(InjectableImplError::ConstructorMethodAsync { - asyncness_span: asyncness.span, - }); + if !is_async { + if let Some(asyncness) = self.constructor_method.sig.asyncness { + return Err( + InjectableImplError::ConstructorMethodAsyncWithMissingAsyncAttr { + asyncness_span: asyncness.span, + }, + ); + } } if !self.constructor_method.sig.generics.params.is_empty() { @@ -235,6 +239,12 @@ impl InjectableImpl .map(|index| format_ident!("dependency_{index}")) .collect::>(); + let maybe_await_constructor = if self.constructor_method.sig.asyncness.is_some() { + quote! { .await } + } else { + quote! {} + }; + quote! { #maybe_doc_hidden impl #generics syrette::interfaces::async_injectable::AsyncInjectable< @@ -273,7 +283,7 @@ impl InjectableImpl Ok(syrette::ptr::TransientPtr::new(Self::#constructor( #(#dependency_idents),* - ))) + )#maybe_await_constructor)) }) } } @@ -522,9 +532,15 @@ pub enum InjectableImplError unsafety_span: Span }, - #[error("Constructor method is not allowed to be async"), span = asyncness_span] - #[note("Required by the 'injectable' attribute macro")] - ConstructorMethodAsync { + #[ + error(concat!( + "Constructor method is not allowed to be async when the 'async' flag of the ", + "'injectable' macro is not set to true" + )), + span = asyncness_span + ] + #[help("Enable the 'async' flag here")] + ConstructorMethodAsyncWithMissingAsyncAttr { asyncness_span: Span }, -- cgit v1.2.3-18-g5258