diff options
Diffstat (limited to 'macros/src/injectable')
-rw-r--r-- | macros/src/injectable/implementation.rs | 105 | ||||
-rw-r--r-- | macros/src/injectable/macro_args.rs | 11 |
2 files changed, 100 insertions, 16 deletions
diff --git a/macros/src/injectable/implementation.rs b/macros/src/injectable/implementation.rs index a67b4a3..a361567 100644 --- a/macros/src/injectable/implementation.rs +++ b/macros/src/injectable/implementation.rs @@ -1,4 +1,4 @@ -use proc_macro2::{Ident, Span}; +use proc_macro2::{Ident, Span, TokenStream}; use quote::{format_ident, quote, ToTokens}; use syn::spanned::Spanned; use syn::{ @@ -12,8 +12,10 @@ use syn::{ ImplItemMethod, ItemImpl, MethodTurbofish, + Path, ReturnType, Type, + TypePath, }; use crate::injectable::dependency::DependencyError; @@ -148,14 +150,13 @@ impl InjectableImpl Ok(()) } - pub fn self_type(&self) -> &Type - { - &self.original_impl.self_ty - } - #[cfg(not(tarpaulin_include))] - pub fn expand(&self, no_doc_hidden: bool, is_async: bool) - -> proc_macro2::TokenStream + pub fn expand( + &self, + no_doc_hidden: bool, + is_async: bool, + interface_trait: Option<&TypePath>, + ) -> proc_macro2::TokenStream { let di_container_var = format_ident!("{}", DI_CONTAINER_VAR_NAME); let dependency_history_var = format_ident!("{}", DEPENDENCY_HISTORY_VAR_NAME); @@ -186,6 +187,7 @@ impl InjectableImpl &dependency_history_var, &maybe_prevent_circular_deps, &get_dep_method_calls, + interface_trait, ) } else { self.expand_blocking_impl( @@ -194,6 +196,7 @@ impl InjectableImpl &dependency_history_var, &maybe_prevent_circular_deps, &get_dep_method_calls, + interface_trait, ) }; @@ -232,12 +235,31 @@ impl InjectableImpl dependency_history_var: &Ident, maybe_prevent_circular_deps: &proc_macro2::TokenStream, get_dep_method_calls: &Vec<proc_macro2::TokenStream>, + interface_trait: Option<&TypePath>, ) -> proc_macro2::TokenStream { let generics = &self.original_impl.generics; let self_type = &self.original_impl.self_ty; let constructor = &self.constructor_method.sig.ident; + let into_ptr_buf_fns = &[ + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Box"), + Path::new_empty(), + ), + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Rc"), + syn_path!(std::rc), + ), + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Arc"), + syn_path!(std::sync), + ), + ] as &[TokenStream]; + let dependency_idents = (0..get_dep_method_calls.len()) .map(|index| format_ident!("dependency_{index}")) .collect::<Vec<_>>(); @@ -289,6 +311,8 @@ impl InjectableImpl )#maybe_await_constructor)) }) } + + #(#into_ptr_buf_fns)* } } } @@ -301,12 +325,31 @@ impl InjectableImpl dependency_history_var: &Ident, maybe_prevent_circular_deps: &proc_macro2::TokenStream, get_dep_method_calls: &Vec<proc_macro2::TokenStream>, + interface_trait: Option<&TypePath>, ) -> proc_macro2::TokenStream { let generics = &self.original_impl.generics; let self_type = &self.original_impl.self_ty; let constructor = &self.constructor_method.sig.ident; + let into_ptr_buf_fns = &[ + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Box"), + Path::new_empty(), + ), + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Rc"), + syn_path!(std::rc), + ), + Self::create_to_ptr_buf_fn( + interface_trait, + &format_ident!("Arc"), + syn_path!(std::sync), + ), + ] as &[TokenStream]; + quote! { #maybe_doc_hidden impl #generics syrette::interfaces::injectable::Injectable< @@ -332,6 +375,52 @@ impl InjectableImpl #(#get_dep_method_calls),* ))); } + + #(#into_ptr_buf_fns)* + } + } + } + + fn create_to_ptr_buf_fn( + interface_trait: Option<&TypePath>, + smart_ptr_ident: &Ident, + smart_ptr_parent_path: Path, + ) -> TokenStream + { + let ptr_buf_path = quote! { syrette::ptr_buffer::PtrBuffer }; + + let mut smart_ptr = smart_ptr_parent_path; + + smart_ptr.segments.push(smart_ptr_ident.clone().into()); + + let body = match interface_trait { + Some(interface_trait) => { + quote! { + let me: #smart_ptr<dyn #interface_trait> = self; + + #ptr_buf_path::new_from( + syrette::ptr_buffer::SmartPtr::#smart_ptr_ident(me) + ) + } + } + None => { + quote! { + #ptr_buf_path::new_from( + syrette::ptr_buffer::SmartPtr::#smart_ptr_ident(self) + ) + } + } + }; + + let into_ptr_buf_fn = format_ident!( + "into_ptr_buffer_{}", + smart_ptr_ident.to_string().to_lowercase() + ); + + quote! { + fn #into_ptr_buf_fn(self: #smart_ptr<Self>) -> #ptr_buf_path + { + #body } } } diff --git a/macros/src/injectable/macro_args.rs b/macros/src/injectable/macro_args.rs index 719d551..f0469f7 100644 --- a/macros/src/injectable/macro_args.rs +++ b/macros/src/injectable/macro_args.rs @@ -7,12 +7,7 @@ use crate::macro_flag::MacroFlag; use crate::util::error::diagnostic_error_enum; use crate::util::iterator_ext::IteratorExt; -pub const INJECTABLE_MACRO_FLAGS: &[&str] = &[ - "no_doc_hidden", - "async", - "no_declare_concrete_interface", - "constructor", -]; +pub const INJECTABLE_MACRO_FLAGS: &[&str] = &["no_doc_hidden", "async", "constructor"]; pub struct InjectableMacroArgs { @@ -194,7 +189,7 @@ mod tests fn can_parse_with_flags_only() { let input_args = quote! { - async = false, no_declare_concrete_interface = false + async = false, no_doc_hidden = false }; let injectable_macro_args = parse2::<InjectableMacroArgs>(input_args).unwrap(); @@ -212,7 +207,7 @@ mod tests ))) }, MacroFlag { - name: format_ident!("no_declare_concrete_interface"), + name: format_ident!("no_doc_hidden"), value: MacroFlagValue::Literal(Lit::Bool(LitBool::new( false, Span::call_site() |