diff options
24 files changed, 107 insertions, 990 deletions
diff --git a/examples/async-factory/main.rs b/examples/async-factory/main.rs index 83f79f0..2b796cc 100644 --- a/examples/async-factory/main.rs +++ b/examples/async-factory/main.rs @@ -7,7 +7,7 @@ use std::time::Duration; use anyhow::Result; use syrette::future::BoxFuture; use syrette::ptr::TransientPtr; -use syrette::{declare_default_factory, factory, AsyncDIContainer}; +use syrette::AsyncDIContainer; use tokio::time::sleep; trait IFoo: Send + Sync @@ -15,7 +15,6 @@ trait IFoo: Send + Sync fn bar(&self); } -#[factory(threadsafe = true)] type IFooFactory = dyn Fn(i32) -> BoxFuture<'static, TransientPtr<dyn IFoo>> + Send + Sync; @@ -68,8 +67,6 @@ impl IPerson for Person } } -declare_default_factory!(dyn IPerson, async = true); - #[tokio::main] async fn main() -> Result<()> { diff --git a/examples/async/bootstrap.rs b/examples/async/bootstrap.rs index 6fbe831..07e1bf8 100644 --- a/examples/async/bootstrap.rs +++ b/examples/async/bootstrap.rs @@ -1,5 +1,5 @@ use syrette::ptr::TransientPtr; -use syrette::{declare_default_factory, AsyncDIContainer}; +use syrette::AsyncDIContainer; use crate::animals::cat::Cat; use crate::animals::dog::Dog; @@ -10,8 +10,6 @@ use crate::interfaces::dog::IDog; use crate::interfaces::food::{IFood, IFoodFactory}; use crate::interfaces::human::IHuman; -declare_default_factory!(dyn ICat, threadsafe = true); - pub async fn bootstrap() -> Result<AsyncDIContainer, anyhow::Error> { let mut di_container = AsyncDIContainer::new(); diff --git a/examples/async/interfaces/food.rs b/examples/async/interfaces/food.rs index 9d88083..21ea568 100644 --- a/examples/async/interfaces/food.rs +++ b/examples/async/interfaces/food.rs @@ -1,4 +1,3 @@ -use syrette::factory; use syrette::ptr::TransientPtr; pub trait IFood: Send + Sync @@ -6,5 +5,4 @@ pub trait IFood: Send + Sync fn eat(&self); } -#[factory(threadsafe = true)] pub type IFoodFactory = dyn Fn() -> TransientPtr<dyn IFood> + Send + Sync; diff --git a/examples/factory/interfaces/user.rs b/examples/factory/interfaces/user.rs index aafd0cb..5a60317 100644 --- a/examples/factory/interfaces/user.rs +++ b/examples/factory/interfaces/user.rs @@ -1,4 +1,3 @@ -use syrette::factory; use syrette::ptr::TransientPtr; pub trait IUser @@ -8,6 +7,5 @@ pub trait IUser fn get_password(&self) -> &'static str; } -#[factory] pub type IUserFactory = dyn Fn(&'static str, &'static str, &'static str) -> TransientPtr<dyn IUser>; diff --git a/examples/with-3rd-party/bootstrap.rs b/examples/with-3rd-party/bootstrap.rs index 5cd0f85..26386f5 100644 --- a/examples/with-3rd-party/bootstrap.rs +++ b/examples/with-3rd-party/bootstrap.rs @@ -1,14 +1,12 @@ use std::error::Error; use syrette::ptr::TransientPtr; -use syrette::{declare_default_factory, DIContainer}; +use syrette::DIContainer; use third_party_lib::Shuriken; use crate::interfaces::ninja::INinja; use crate::ninja::Ninja; -declare_default_factory!(Shuriken); - pub fn bootstrap() -> Result<DIContainer, Box<dyn Error>> { let mut di_container = DIContainer::new(); diff --git a/macros/src/factory/build_declare_interfaces.rs b/macros/src/factory/build_declare_interfaces.rs deleted file mode 100644 index 1e2d62e..0000000 --- a/macros/src/factory/build_declare_interfaces.rs +++ /dev/null @@ -1,52 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; - -use crate::fn_trait::FnTrait; - -pub fn build_declare_factory_interfaces( - factory_interface: &FnTrait, - is_threadsafe: bool, -) -> TokenStream -{ - if is_threadsafe { - quote! { - syrette::declare_interface!( - syrette::private::castable_factory::threadsafe::ThreadsafeCastableFactory< - #factory_interface, - syrette::di_container::asynchronous::AsyncDIContainer, - > -> syrette::private::factory::IThreadsafeFactory< - #factory_interface, - syrette::di_container::asynchronous::AsyncDIContainer, - >, - threadsafe_sharable = true - ); - - syrette::declare_interface!( - syrette::private::castable_factory::threadsafe::ThreadsafeCastableFactory< - #factory_interface, - syrette::di_container::asynchronous::AsyncDIContainer, - > -> syrette::private::any_factory::AnyThreadsafeFactory, - threadsafe_sharable = true - ); - } - } else { - quote! { - syrette::declare_interface!( - syrette::private::castable_factory::CastableFactory< - #factory_interface, - syrette::di_container::blocking::DIContainer - > -> syrette::private::factory::IFactory< - #factory_interface, - syrette::di_container::blocking::DIContainer - > - ); - - syrette::declare_interface!( - syrette::private::castable_factory::CastableFactory< - #factory_interface, - syrette::di_container::blocking::DIContainer - > -> syrette::private::any_factory::AnyFactory - ); - } - } -} diff --git a/macros/src/factory/declare_default_args.rs b/macros/src/factory/declare_default_args.rs deleted file mode 100644 index 9930f4f..0000000 --- a/macros/src/factory/declare_default_args.rs +++ /dev/null @@ -1,232 +0,0 @@ -use syn::parse::Parse; -use syn::punctuated::Punctuated; -use syn::{Token, Type}; - -use crate::macro_flag::MacroFlag; -use crate::util::iterator_ext::IteratorExt; - -pub const FACTORY_MACRO_FLAGS: &[&str] = &["threadsafe", "async"]; - -pub struct DeclareDefaultFactoryMacroArgs -{ - pub interface: Type, - pub flags: Punctuated<MacroFlag, Token![,]>, -} - -impl Parse for DeclareDefaultFactoryMacroArgs -{ - fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> - { - let interface = input.parse()?; - - if !input.peek(Token![,]) { - return Ok(Self { - interface, - flags: Punctuated::new(), - }); - } - - input.parse::<Token![,]>()?; - - let flags = Punctuated::<MacroFlag, Token![,]>::parse_terminated(input)?; - - for flag in &flags { - let name = flag.name().to_string(); - - if !FACTORY_MACRO_FLAGS.contains(&name.as_str()) { - return Err(input.error(format!( - "Unknown flag '{name}'. Expected one of [ {} ]", - FACTORY_MACRO_FLAGS.join(",") - ))); - } - } - - let flag_names = flags - .iter() - .map(|flag| flag.name().to_string()) - .collect::<Vec<_>>(); - - if let Some((dupe_flag_name, _)) = flag_names.iter().find_duplicate() { - return Err(input.error(format!("Duplicate flag '{dupe_flag_name}'"))); - } - - Ok(Self { interface, flags }) - } -} - -#[cfg(test)] -mod tests -{ - use proc_macro2::Span; - use quote::{format_ident, quote}; - use syn::token::Dyn; - use syn::{ - parse2, - Lit, - LitBool, - Path, - PathArguments, - PathSegment, - TraitBound, - TraitBoundModifier, - Type, - TypeParamBound, - TypeTraitObject, - }; - - use super::*; - use crate::macro_flag::MacroFlagValue; - - #[test] - fn can_parse_with_interface_only() - { - let input_args = quote! { - dyn IFoo - }; - - let dec_def_fac_args = - parse2::<DeclareDefaultFactoryMacroArgs>(input_args).unwrap(); - - assert_eq!( - dec_def_fac_args.interface, - Type::TraitObject(TypeTraitObject { - dyn_token: Some(Dyn::default()), - bounds: Punctuated::from_iter(vec![TypeParamBound::Trait(TraitBound { - paren_token: None, - modifier: TraitBoundModifier::None, - lifetimes: None, - path: Path { - leading_colon: None, - segments: Punctuated::from_iter(vec![PathSegment { - ident: format_ident!("IFoo"), - arguments: PathArguments::None - }]) - } - })]) - }) - ); - - assert!(dec_def_fac_args.flags.is_empty()); - } - - #[test] - fn can_parse_with_interface_and_single_flag() - { - let input_args = quote! { - dyn IBar, threadsafe = true - }; - - let dec_def_fac_args = - parse2::<DeclareDefaultFactoryMacroArgs>(input_args).unwrap(); - - assert_eq!( - dec_def_fac_args.interface, - Type::TraitObject(TypeTraitObject { - dyn_token: Some(Dyn::default()), - bounds: Punctuated::from_iter(vec![TypeParamBound::Trait(TraitBound { - paren_token: None, - modifier: TraitBoundModifier::None, - lifetimes: None, - path: Path { - leading_colon: None, - segments: Punctuated::from_iter(vec![PathSegment { - ident: format_ident!("IBar"), - arguments: PathArguments::None - }]) - } - })]) - }) - ); - - assert_eq!( - dec_def_fac_args.flags, - Punctuated::from_iter(vec![MacroFlag { - name: format_ident!("threadsafe"), - value: MacroFlagValue::Literal(Lit::Bool(LitBool::new( - true, - Span::call_site() - ))) - }]) - ); - } - - #[test] - fn can_parse_with_interface_and_multiple_flags() - { - let input_args = quote! { - dyn IBar, threadsafe = true, async = false - }; - - let dec_def_fac_args = - parse2::<DeclareDefaultFactoryMacroArgs>(input_args).unwrap(); - - assert_eq!( - dec_def_fac_args.interface, - Type::TraitObject(TypeTraitObject { - dyn_token: Some(Dyn::default()), - bounds: Punctuated::from_iter(vec![TypeParamBound::Trait(TraitBound { - paren_token: None, - modifier: TraitBoundModifier::None, - lifetimes: None, - path: Path { - leading_colon: None, - segments: Punctuated::from_iter(vec![PathSegment { - ident: format_ident!("IBar"), - arguments: PathArguments::None - }]) - } - })]) - }) - ); - - assert_eq!( - dec_def_fac_args.flags, - Punctuated::from_iter(vec![ - MacroFlag { - name: format_ident!("threadsafe"), - value: MacroFlagValue::Literal(Lit::Bool(LitBool::new( - true, - Span::call_site() - ))) - }, - MacroFlag { - name: format_ident!("async"), - value: MacroFlagValue::Literal(Lit::Bool(LitBool::new( - false, - Span::call_site() - ))) - } - ]) - ); - } - - #[test] - fn cannot_parse_with_interface_and_invalid_flag() - { - let input_args = quote! { - dyn IBar, async = true, foo = false - }; - - assert!(parse2::<DeclareDefaultFactoryMacroArgs>(input_args).is_err()); - } - - #[test] - fn cannot_parse_with_interface_and_duplicate_flag() - { - assert!( - // Formatting is weird without this comment - parse2::<DeclareDefaultFactoryMacroArgs>(quote! { - dyn IBar, async = true, threadsafe = false, async = true - }) - .is_err() - ); - - assert!( - // Formatting is weird without this comment - parse2::<DeclareDefaultFactoryMacroArgs>(quote! { - dyn IBar, async = true, threadsafe = false, async = false - }) - .is_err() - ); - } -} diff --git a/macros/src/factory/macro_args.rs b/macros/src/factory/macro_args.rs deleted file mode 100644 index 676b412..0000000 --- a/macros/src/factory/macro_args.rs +++ /dev/null @@ -1,106 +0,0 @@ -use syn::parse::Parse; -use syn::punctuated::Punctuated; -use syn::Token; - -use crate::macro_flag::MacroFlag; -use crate::util::iterator_ext::IteratorExt; - -pub const FACTORY_MACRO_FLAGS: &[&str] = &["threadsafe"]; - -pub struct FactoryMacroArgs -{ - pub flags: Punctuated<MacroFlag, Token![,]>, -} - -impl Parse for FactoryMacroArgs -{ - fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> - { - let flags = Punctuated::<MacroFlag, Token![,]>::parse_terminated(input)?; - - for flag in &flags { - let name = flag.name().to_string(); - - if !FACTORY_MACRO_FLAGS.contains(&name.as_str()) { - return Err(input.error(format!( - "Unknown flag '{}'. Expected one of [ {} ]", - name, - FACTORY_MACRO_FLAGS.join(",") - ))); - } - } - - let flag_names = flags - .iter() - .map(|flag| flag.name().to_string()) - .collect::<Vec<_>>(); - - if let Some((dupe_flag_name, _)) = flag_names.iter().find_duplicate() { - return Err(input.error(format!("Duplicate flag '{dupe_flag_name}'"))); - } - - Ok(Self { flags }) - } -} - -#[cfg(test)] -mod tests -{ - use proc_macro2::Span; - use quote::{format_ident, quote}; - use syn::{parse2, Lit, LitBool}; - - use super::*; - use crate::macro_flag::MacroFlagValue; - - #[test] - fn can_parse_with_single_flag() - { - let input_args = quote! { - threadsafe = true - }; - - let factory_macro_args = parse2::<FactoryMacroArgs>(input_args).unwrap(); - - assert_eq!( - factory_macro_args.flags, - Punctuated::from_iter(vec![MacroFlag { - name: format_ident!("threadsafe"), - value: MacroFlagValue::Literal(Lit::Bool(LitBool::new( - true, - Span::call_site() - ))) - }]) - ); - } - - #[test] - fn cannot_parse_with_invalid_flag() - { - let input_args = quote! { - threadsafe = false, foo = true - }; - - assert!(parse2::<FactoryMacroArgs>(input_args).is_err()); - } - - #[test] - fn cannot_parse_with_duplicate_flag() - { - assert!( - // Formatting is weird without this comment - parse2::<FactoryMacroArgs>(quote! { - threadsafe = true, threadsafe = true - }) - .is_err() - ); - - assert!( - // Formatting is weird without this comment - parse2::<FactoryMacroArgs>(quote! { - threadsafe = true, threadsafe = false - }) - .is_err() - ); - } -} diff --git a/macros/src/factory/mod.rs b/macros/src/factory/mod.rs deleted file mode 100644 index 18bad8f..0000000 --- a/macros/src/factory/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub mod build_declare_interfaces; -pub mod declare_default_args; -pub mod macro_args; -pub mod type_alias; diff --git a/macros/src/factory/type_alias.rs b/macros/src/factory/type_alias.rs deleted file mode 100644 index cfa254f..0000000 --- a/macros/src/factory/type_alias.rs +++ /dev/null @@ -1,68 +0,0 @@ -use quote::ToTokens; -use syn::parse::{Parse, ParseStream}; -use syn::{parse2, ItemType}; - -use crate::fn_trait::FnTrait; - -pub struct FactoryTypeAlias -{ - pub type_alias: ItemType, - pub factory_interface: FnTrait, -} - -impl Parse for FactoryTypeAlias -{ - fn parse(input: ParseStream) -> syn::Result<Self> - { - let type_alias = input - .parse::<ItemType>() - .map_err(|_| input.error("Expected a type alias"))?; - - let aliased_fn_trait = - parse2::<FnTrait>(type_alias.ty.as_ref().to_token_stream())?; - - Ok(Self { - type_alias, - factory_interface: aliased_fn_trait.clone(), - }) - } -} - -#[cfg(test)] -mod tests -{ - use quote::{format_ident, quote}; - use syn::punctuated::Punctuated; - use syn::token::And; - use syn::{Type, TypeReference}; - - use super::*; - use crate::test_utils; - - #[test] - fn can_parse() - { - let input_args = quote! { - type FooFactory = dyn Fn(String, &u32) -> Foo; - }; - - let factory_type_alias = parse2::<FactoryTypeAlias>(input_args).unwrap(); - - assert_eq!( - factory_type_alias.factory_interface.inputs, - Punctuated::from_iter(vec![ - test_utils::create_type(test_utils::create_path(&[ - test_utils::create_path_segment(format_ident!("String"), &[]) - ])), - Type::Reference(TypeReference { - and_token: And::default(), - lifetime: None, - mutability: None, - elem: Box::new(test_utils::create_type(test_utils::create_path(&[ - test_utils::create_path_segment(format_ident!("u32"), &[]) - ]))) - }) - ]) - ); - } -} diff --git a/macros/src/fn_trait.rs b/macros/src/fn_trait.rs deleted file mode 100644 index 0858cca..0000000 --- a/macros/src/fn_trait.rs +++ /dev/null @@ -1,162 +0,0 @@ -use quote::ToTokens; -use syn::parse::Parse; -use syn::punctuated::Punctuated; -use syn::token::Paren; -use syn::{parenthesized, Ident, Token, TraitBound, Type}; - -/// A function trait. `dyn Fn(u32) -> String` -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FnTrait -{ - pub dyn_token: Token![dyn], - pub trait_ident: Ident, - pub paren_token: Paren, - pub inputs: Punctuated<Type, Token![,]>, - pub r_arrow_token: Token![->], - pub output: Type, - pub trait_bounds: Punctuated<TraitBound, Token![+]>, -} - -impl FnTrait -{ - pub fn add_trait_bound(&mut self, trait_bound: TraitBound) - { - self.trait_bounds.push(trait_bound); - } -} - -impl Parse for FnTrait -{ - fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> - { - let dyn_token = input.parse::<Token![dyn]>()?; - - let trait_ident = input.parse::<Ident>()?; - - if trait_ident.to_string().as_str() != "Fn" { - return Err(syn::Error::new(trait_ident.span(), "Expected 'Fn'")); - } - - let content; - - let paren_token = parenthesized!(content in input); - - let inputs = content.parse_terminated(Type::parse)?; - - let r_arrow_token = input.parse::<Token![->]>()?; - - let output = input.parse::<Type>()?; - - Ok(Self { - dyn_token, - trait_ident, - paren_token, - inputs, - r_arrow_token, - output, - trait_bounds: Punctuated::new(), - }) - } -} - -impl ToTokens for FnTrait -{ - fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) - { - self.dyn_token.to_tokens(tokens); - - self.trait_ident.to_tokens(tokens); - - self.paren_token.surround(tokens, |tokens_inner| { - self.inputs.to_tokens(tokens_inner); - }); - - self.r_arrow_token.to_tokens(tokens); - - self.output.to_tokens(tokens); - - if !self.trait_bounds.is_empty() { - let plus = <Token![+]>::default(); - - plus.to_tokens(tokens); - - self.trait_bounds.to_tokens(tokens); - } - } -} - -#[cfg(test)] -mod tests -{ - use quote::{format_ident, quote}; - use syn::token::{Dyn, RArrow}; - use syn::{parse2, PathSegment}; - - use super::*; - use crate::test_utils; - - #[test] - fn can_parse_fn_trait() - { - assert_eq!( - parse2::<FnTrait>(quote! { - dyn Fn(String, u32) -> Handle - }) - .unwrap(), - FnTrait { - dyn_token: Dyn::default(), - trait_ident: format_ident!("Fn"), - paren_token: Paren::default(), - inputs: Punctuated::from_iter(vec![ - test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("String")) - ])), - test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("u32")) - ])) - ]), - r_arrow_token: RArrow::default(), - output: test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("Handle")) - ])), - trait_bounds: Punctuated::new() - } - ); - - assert!(parse2::<FnTrait>(quote! { - Fn(u32) -> Handle - }) - .is_err()); - } - - #[test] - fn can_parse_fn_trait_to_tokens() - { - assert_eq!( - FnTrait { - dyn_token: Dyn::default(), - trait_ident: format_ident!("Fn"), - paren_token: Paren::default(), - inputs: Punctuated::from_iter(vec![ - test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("Bread")) - ])), - test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("Cheese")) - ])), - test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("Tomatoes")) - ])) - ]), - r_arrow_token: RArrow::default(), - output: test_utils::create_type(test_utils::create_path(&[ - PathSegment::from(format_ident!("Taco")) - ])), - trait_bounds: Punctuated::new() - } - .into_token_stream() - .to_string(), - "dyn Fn (Bread , Cheese , Tomatoes) -> Taco".to_string() - ); - } -} diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 7928e03..fa84e0e 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -35,12 +35,6 @@ mod injectable; mod macro_flag; mod util; -#[cfg(feature = "factory")] -mod factory; - -#[cfg(feature = "factory")] -mod fn_trait; - #[cfg(test)] mod test_utils; @@ -277,158 +271,6 @@ pub fn injectable(args_stream: TokenStream, input_stream: TokenStream) -> TokenS .into() } -/// Makes a type alias usable as a factory interface. -/// -/// # Arguments -/// * (Zero or more) Flags. Like `a = true, b = false` -/// -/// # Flags -/// - `threadsafe` - Mark as threadsafe. -/// -/// # Examples -/// ``` -/// # use syrette::factory; -/// # use syrette::ptr::TransientPtr; -/// # -/// # trait IConfigurator {} -/// # -/// # struct Configurator {} -/// # -/// # impl Configurator -/// # { -/// # fn new() -> Self -/// # { -/// # Self {} -/// # } -/// # } -/// # -/// # impl IConfigurator for Configurator {} -/// # -/// #[factory] -/// type IConfiguratorFactory = dyn Fn(Vec<String>) -> TransientPtr<dyn IConfigurator>; -/// ``` -/// -/// [`TransientPtr`]: https://docs.rs/syrette/latest/syrette/ptr/type.TransientPtr.html -#[cfg(feature = "factory")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -#[cfg(not(tarpaulin_include))] -#[proc_macro_error] -#[proc_macro_attribute] -pub fn factory(args_stream: TokenStream, input_stream: TokenStream) -> TokenStream -{ - use crate::factory::build_declare_interfaces::build_declare_factory_interfaces; - use crate::factory::macro_args::FactoryMacroArgs; - use crate::factory::type_alias::FactoryTypeAlias; - - set_dummy(input_stream.clone().into()); - - let FactoryMacroArgs { flags } = parse(args_stream).unwrap_or_abort(); - - let is_threadsafe = flags - .iter() - .find(|flag| flag.name() == "threadsafe") - .map_or(Ok(false), MacroFlag::get_bool) - .unwrap_or_abort(); - - let FactoryTypeAlias { - type_alias, - factory_interface, - } = parse(input_stream).unwrap_or_abort(); - - let decl_interfaces = - build_declare_factory_interfaces(&factory_interface, is_threadsafe); - - quote! { - #type_alias - - #decl_interfaces - } - .into() -} - -/// Shortcut for declaring a default factory. -/// -/// A default factory is a factory that doesn't take any arguments. -/// -/// Another way to accomplish what this macro does would be by using -/// the [`macro@factory`] macro. -/// -/// # Arguments -/// - Interface trait -/// * (Zero or more) Flags. Like `a = true, b = false` -/// -/// # Flags -/// - `threadsafe` - Mark as threadsafe. -/// - `async` - Mark as async. Infers the `threadsafe` flag. -/// -/// # Examples -/// ``` -/// # use syrette::declare_default_factory; -/// # -/// trait IParser -/// { -/// // Methods and etc here... -/// } -/// -/// declare_default_factory!(dyn IParser); -/// ``` -#[cfg(feature = "factory")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -#[cfg(not(tarpaulin_include))] -#[proc_macro_error] -#[proc_macro] -pub fn declare_default_factory(args_stream: TokenStream) -> TokenStream -{ - use syn::parse_str; - - use crate::factory::build_declare_interfaces::build_declare_factory_interfaces; - use crate::factory::declare_default_args::DeclareDefaultFactoryMacroArgs; - use crate::fn_trait::FnTrait; - - let DeclareDefaultFactoryMacroArgs { interface, flags } = - parse(args_stream).unwrap_or_abort(); - - let mut is_threadsafe = flags - .iter() - .find(|flag| flag.name() == "threadsafe") - .map_or(Ok(false), MacroFlag::get_bool) - .unwrap_or_abort(); - - let is_async = flags - .iter() - .find(|flag| flag.name() == "async") - .map_or(Ok(false), MacroFlag::get_bool) - .unwrap_or_abort(); - - if is_async { - is_threadsafe = true; - } - - let mut factory_interface: FnTrait = parse( - if is_async { - quote! { - dyn Fn() -> syrette::future::BoxFuture< - 'static, - syrette::ptr::TransientPtr<#interface> - > - } - } else { - quote! { - dyn Fn() -> syrette::ptr::TransientPtr<#interface> - } - } - .into(), - ) - .unwrap_or_abort(); - - if is_threadsafe { - factory_interface.add_trait_bound(parse_str("Send").unwrap_or_abort()); - factory_interface.add_trait_bound(parse_str("Sync").unwrap_or_abort()); - } - - build_declare_factory_interfaces(&factory_interface, is_threadsafe).into() -} - /// Declares the interface trait of a implementation. /// /// # Arguments diff --git a/src/private/any_factory.rs b/src/any_factory.rs index 64af57e..3aee98f 100644 --- a/src/private/any_factory.rs +++ b/src/any_factory.rs @@ -1,11 +1,13 @@ //! Interface for any factory to ever exist. +use std::any::Any; use std::fmt::Debug; -use crate::private::cast::{CastFrom, CastFromArc}; - /// Interface for any factory to ever exist. -pub trait AnyFactory: CastFrom + Debug {} +pub trait AnyFactory: Any + Debug +{ + fn as_any(&self) -> &dyn Any; +} /// Interface for any threadsafe factory to ever exist. -pub trait AnyThreadsafeFactory: CastFromArc + Debug {} +pub trait AnyThreadsafeFactory: AnyFactory + Send + Sync + Debug {} diff --git a/src/private/castable_factory/mod.rs b/src/castable_factory/mod.rs index 2ac5918..196dc14 100644 --- a/src/private/castable_factory/mod.rs +++ b/src/castable_factory/mod.rs @@ -1,8 +1,7 @@ -use std::any::type_name; +use std::any::{type_name, Any}; use std::fmt::Debug; -use crate::private::any_factory::AnyFactory; -use crate::private::factory::IFactory; +use crate::any_factory::AnyFactory; use crate::ptr::TransientPtr; #[cfg(feature = "async")] @@ -26,14 +25,8 @@ where { Self { func } } -} -impl<ReturnInterface, DIContainerT> IFactory<ReturnInterface, DIContainerT> - for CastableFactory<ReturnInterface, DIContainerT> -where - ReturnInterface: 'static + ?Sized, -{ - fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> + pub fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> { (self.func)(di_container) } @@ -45,6 +38,10 @@ where ReturnInterface: 'static + ?Sized, DIContainerT: 'static, { + fn as_any(&self) -> &dyn Any + { + self + } } impl<ReturnInterface, DIContainerT> Debug diff --git a/src/private/castable_factory/threadsafe.rs b/src/castable_factory/threadsafe.rs index 6e8da42..5935d75 100644 --- a/src/private/castable_factory/threadsafe.rs +++ b/src/castable_factory/threadsafe.rs @@ -1,8 +1,7 @@ -use std::any::type_name; +use std::any::{type_name, Any}; use std::fmt::Debug; -use crate::private::any_factory::{AnyFactory, AnyThreadsafeFactory}; -use crate::private::factory::IThreadsafeFactory; +use crate::any_factory::{AnyFactory, AnyThreadsafeFactory}; use crate::ptr::TransientPtr; pub struct ThreadsafeCastableFactory<ReturnInterface, DIContainerT> @@ -27,15 +26,8 @@ where { Self { func } } -} -impl<ReturnInterface, DIContainerT> IThreadsafeFactory<ReturnInterface, DIContainerT> - for ThreadsafeCastableFactory<ReturnInterface, DIContainerT> -where - DIContainerT: 'static, - ReturnInterface: 'static + ?Sized, -{ - fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> + pub fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> { (self.func)(di_container) } @@ -47,6 +39,10 @@ where DIContainerT: 'static, ReturnInterface: 'static + ?Sized, { + fn as_any(&self) -> &dyn Any + { + self + } } impl<ReturnInterface, DIContainerT> AnyThreadsafeFactory diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs index 5e77c24..f42e6a1 100644 --- a/src/di_container/asynchronous/binding/builder.rs +++ b/src/di_container/asynchronous/binding/builder.rs @@ -127,7 +127,6 @@ where /// ``` /// # use std::error::Error; /// # - /// # use syrette::{factory}; /// # use syrette::AsyncDIContainer; /// # use syrette::ptr::TransientPtr; /// # @@ -141,7 +140,6 @@ where /// # /// # impl Foo for Bar {} /// # - /// # #[factory(threadsafe = true)] /// # type FooFactory = dyn Fn(i32, String) -> TransientPtr<dyn Foo> + Send + Sync; /// # /// # #[tokio::main] @@ -175,7 +173,7 @@ where Interface: Fn<Args, Output = Return> + Send + Sync, FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<Args, Return> + Send + Sync, { - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; if self @@ -213,7 +211,6 @@ where /// # use std::error::Error; /// # use std::time::Duration; /// # - /// # use syrette::{factory}; /// # use syrette::AsyncDIContainer; /// # use syrette::ptr::TransientPtr; /// # use syrette::future::BoxFuture; @@ -228,7 +225,6 @@ where /// # /// # impl Foo for Bar {} /// # - /// # #[factory] /// # type FooFactory = dyn Fn(i32, String) -> BoxFuture< /// # 'static, /// # TransientPtr<dyn Foo> @@ -274,7 +270,7 @@ where + Send + Sync, { - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; if self @@ -358,7 +354,7 @@ where + Send + Sync, { - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; if self @@ -449,7 +445,7 @@ where + Send + Sync, { - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::provider::r#async::AsyncFactoryVariant; if self @@ -516,11 +512,8 @@ mod tests #[cfg(feature = "factory")] async fn can_bind_to_factory() { - use crate as syrette; - use crate::factory; use crate::ptr::TransientPtr; - #[factory(threadsafe = true)] type IUserManagerFactory = dyn Fn( String, i32, @@ -567,10 +560,8 @@ mod tests use crate::future::BoxFuture; use crate::ptr::TransientPtr; use crate::test_utils::async_closure; - use crate::{self as syrette, factory}; #[rustfmt::skip] - #[factory] type IUserManagerFactory = dyn Fn(String) -> BoxFuture< 'static, TransientPtr<dyn subjects_async::IUserManager> @@ -611,13 +602,8 @@ mod tests #[cfg(feature = "factory")] async fn can_bind_to_default_factory() { - use syrette_macros::declare_default_factory; - - use crate as syrette; use crate::ptr::TransientPtr; - declare_default_factory!(dyn subjects_async::IUserManager); - let mut di_container_mock = MockAsyncDIContainer::new(); di_container_mock @@ -654,13 +640,8 @@ mod tests #[cfg(feature = "factory")] async fn can_bind_to_async_default_factory() { - use syrette_macros::declare_default_factory; - use crate::ptr::TransientPtr; use crate::test_utils::async_closure; - use crate::{self as syrette}; - - declare_default_factory!(dyn subjects_async::IUserManager, async = true); let mut di_container_mock = MockAsyncDIContainer::new(); diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous/mod.rs index 403ea18..3e29ef6 100644 --- a/src/di_container/asynchronous/mod.rs +++ b/src/di_container/asynchronous/mod.rs @@ -348,95 +348,64 @@ impl AsyncDIContainer } #[cfg(feature = "factory")] AsyncProvidable::Factory(factory_binding) => { - use crate::private::factory::IThreadsafeFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; let factory = factory_binding - .cast::<dyn IThreadsafeFactory<Interface, Self>>() - .map_err(|err| match err { - CastError::NotArcCastable(_) => { - AsyncDIContainerError::InterfaceNotAsync( - type_name::<Interface>(), - ) - } - CastError::CastFailed { - source: _, - from: _, - to: _, - } - | CastError::GetCasterFailed(_) => { - AsyncDIContainerError::CastFailed { - interface: type_name::<Interface>(), - binding_kind: "factory", - } - } + .as_any() + .downcast_ref::<ThreadsafeCastableFactory<Interface, Self>>() + .ok_or_else(|| AsyncDIContainerError::CastFailed { + interface: type_name::<Interface>(), + binding_kind: "factory", })?; Ok(SomePtr::ThreadsafeFactory(factory.call(self).into())) } #[cfg(feature = "factory")] AsyncProvidable::DefaultFactory(binding) => { - use crate::private::factory::IThreadsafeFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::ptr::TransientPtr; - type DefaultFactoryFn<Interface> = dyn IThreadsafeFactory< - dyn Fn<(), Output = TransientPtr<Interface>> + Send + Sync, + type DefaultFactoryFn<Interface> = ThreadsafeCastableFactory< + dyn Fn() -> TransientPtr<Interface> + Send + Sync, AsyncDIContainer, >; - let default_factory = Self::cast_factory_binding::< - DefaultFactoryFn<Interface>, - >(binding, "default factory")?; + let default_factory = binding + .as_any() + .downcast_ref::<DefaultFactoryFn<Interface>>() + .ok_or_else(|| AsyncDIContainerError::CastFailed { + interface: type_name::<DefaultFactoryFn<Interface>>(), + binding_kind: "default factory", + })?; Ok(SomePtr::Transient(default_factory.call(self)())) } #[cfg(feature = "factory")] AsyncProvidable::AsyncDefaultFactory(binding) => { + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; use crate::future::BoxFuture; - use crate::private::factory::IThreadsafeFactory; use crate::ptr::TransientPtr; - type AsyncDefaultFactoryFn<Interface> = dyn IThreadsafeFactory< + type AsyncDefaultFactoryFn<Interface> = ThreadsafeCastableFactory< dyn Fn<(), Output = BoxFuture<'static, TransientPtr<Interface>>> + Send + Sync, AsyncDIContainer, >; - let async_default_factory = Self::cast_factory_binding::< - AsyncDefaultFactoryFn<Interface>, - >( - binding, "async default factory" - )?; + let async_default_factory = binding + .as_any() + .downcast_ref::<AsyncDefaultFactoryFn<Interface>>() + .ok_or_else(|| AsyncDIContainerError::CastFailed { + interface: type_name::<AsyncDefaultFactoryFn<Interface>>(), + binding_kind: "async default factory", + })?; Ok(SomePtr::Transient(async_default_factory.call(self)().await)) } } } - #[cfg(feature = "factory")] - fn cast_factory_binding<Type: 'static + ?Sized>( - factory_binding: std::sync::Arc< - dyn crate::private::any_factory::AnyThreadsafeFactory, - >, - binding_kind: &'static str, - ) -> Result<std::sync::Arc<Type>, AsyncDIContainerError> - { - factory_binding.cast::<Type>().map_err(|err| match err { - CastError::NotArcCastable(_) => { - AsyncDIContainerError::InterfaceNotAsync(type_name::<Type>()) - } - CastError::CastFailed { - source: _, - from: _, - to: _, - } - | CastError::GetCasterFailed(_) => AsyncDIContainerError::CastFailed { - interface: type_name::<Type>(), - binding_kind, - }, - }) - } - async fn get_binding_providable<Interface>( &self, binding_options: BindingOptions<'static>, @@ -683,10 +652,8 @@ mod tests } } - use crate as syrette; - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; - #[crate::factory(threadsafe = true)] type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync; @@ -767,10 +734,8 @@ mod tests } } - use crate as syrette; - use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory; + use crate::castable_factory::threadsafe::ThreadsafeCastableFactory; - #[crate::factory(threadsafe = true)] type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync; diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs index f322809..9f7f6f9 100644 --- a/src/di_container/blocking/binding/builder.rs +++ b/src/di_container/blocking/binding/builder.rs @@ -119,7 +119,7 @@ where /// ``` /// # use std::error::Error; /// # - /// # use syrette::{DIContainer, factory}; + /// # use syrette::DIContainer; /// # use syrette::ptr::TransientPtr; /// # /// # trait ICustomerID {} @@ -140,10 +140,8 @@ where /// # /// # impl ICustomer for Customer {} /// # - /// # #[factory] /// # type ICustomerFactory = dyn Fn(String, u32) -> TransientPtr<dyn ICustomer>; /// # - /// # #[factory] /// # type ICustomerIDFactory = dyn Fn(u32) -> TransientPtr<dyn ICustomerID>; /// # /// # fn main() -> Result<(), Box<dyn Error>> @@ -183,7 +181,7 @@ where Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>, Func: Fn(&DIContainer) -> Box<Interface>, { - use crate::private::castable_factory::CastableFactory; + use crate::castable_factory::CastableFactory; if self .di_container @@ -218,7 +216,7 @@ where /// ``` /// # use std::error::Error; /// # - /// # use syrette::{DIContainer, factory}; + /// # use syrette::DIContainer; /// # use syrette::ptr::TransientPtr; /// # /// # trait IBuffer {} @@ -271,7 +269,7 @@ where dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>, >, { - use crate::private::castable_factory::CastableFactory; + use crate::castable_factory::CastableFactory; if self .di_container @@ -335,11 +333,8 @@ mod tests #[cfg(feature = "factory")] fn can_bind_to_factory() { - use crate as syrette; - use crate::factory; use crate::ptr::TransientPtr; - #[factory] type IUserManagerFactory = dyn Fn(i32, String) -> TransientPtr<dyn subjects::IUserManager>; @@ -378,13 +373,8 @@ mod tests #[cfg(feature = "factory")] fn can_bind_to_default_factory() { - use syrette_macros::declare_default_factory; - - use crate as syrette; use crate::ptr::TransientPtr; - declare_default_factory!(dyn subjects::IUserManager); - let mut mock_di_container = MockDIContainer::new(); mock_di_container diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs index 65e697e..d9efe94 100644 --- a/src/di_container/blocking/mod.rs +++ b/src/di_container/blocking/mod.rs @@ -285,11 +285,12 @@ impl DIContainer )), #[cfg(feature = "factory")] Providable::Factory(factory_binding) => { - use crate::private::factory::IFactory; + use crate::castable_factory::CastableFactory; let factory = factory_binding - .cast::<dyn IFactory<Interface, Self>>() - .map_err(|_| DIContainerError::CastFailed { + .as_any() + .downcast_ref::<CastableFactory<Interface, Self>>() + .ok_or_else(|| DIContainerError::CastFailed { interface: type_name::<Interface>(), binding_kind: "factory", })?; @@ -298,17 +299,16 @@ impl DIContainer } #[cfg(feature = "factory")] Providable::DefaultFactory(factory_binding) => { - use crate::private::factory::IFactory; + use crate::castable_factory::CastableFactory; use crate::ptr::TransientPtr; - type DefaultFactoryFn<Interface> = dyn IFactory< - dyn Fn<(), Output = TransientPtr<Interface>>, - DIContainer, - >; + type DefaultFactoryFn<Interface> = + CastableFactory<dyn Fn() -> TransientPtr<Interface>, DIContainer>; let default_factory = factory_binding - .cast::<DefaultFactoryFn<Interface>>() - .map_err(|_| DIContainerError::CastFailed { + .as_any() + .downcast_ref::<DefaultFactoryFn<Interface>>() + .ok_or_else(|| DIContainerError::CastFailed { interface: type_name::<Interface>(), binding_kind: "default factory", })?; @@ -517,7 +517,7 @@ mod tests #[cfg(feature = "factory")] fn can_get_factory() { - use crate::private::castable_factory::CastableFactory; + use crate::castable_factory::CastableFactory; use crate::ptr::FactoryPtr; trait IUserManager @@ -556,9 +556,6 @@ mod tests } } - use crate as syrette; - - #[crate::factory] type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>; let mut di_container = DIContainer::new(); @@ -595,7 +592,7 @@ mod tests #[cfg(feature = "factory")] fn can_get_factory_named() { - use crate::private::castable_factory::CastableFactory; + use crate::castable_factory::CastableFactory; use crate::ptr::FactoryPtr; trait IUserManager @@ -634,9 +631,6 @@ mod tests } } - use crate as syrette; - - #[crate::factory] type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>; let mut di_container = DIContainer::new(); @@ -102,9 +102,6 @@ pub mod future; #[cfg_attr(doc_cfg, doc(cfg(feature = "async")))] pub use di_container::asynchronous::AsyncDIContainer; pub use di_container::blocking::DIContainer; -#[cfg(feature = "factory")] -#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -pub use syrette_macros::{declare_default_factory, factory}; pub use syrette_macros::{declare_interface, injectable, named}; #[doc(hidden)] @@ -113,6 +110,12 @@ pub mod private; mod provider; mod util; +#[cfg(feature = "factory")] +mod castable_factory; + +#[cfg(feature = "factory")] +mod any_factory; + #[cfg(test)] #[cfg(not(tarpaulin_include))] mod test_utils; diff --git a/src/private/factory.rs b/src/private/factory.rs deleted file mode 100644 index 7191c2c..0000000 --- a/src/private/factory.rs +++ /dev/null @@ -1,20 +0,0 @@ -use crate::private::cast::CastFrom; -use crate::ptr::TransientPtr; - -/// Interface for a factory. -pub trait IFactory<ReturnInterface, DIContainerT>: CastFrom -where - ReturnInterface: 'static + ?Sized, -{ - fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface>; -} - -/// Interface for a threadsafe factory. -#[cfg(feature = "async")] -pub trait IThreadsafeFactory<ReturnInterface, DIContainerT>: - crate::private::cast::CastFromArc -where - ReturnInterface: 'static + ?Sized, -{ - fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface>; -} diff --git a/src/private/mod.rs b/src/private/mod.rs index 8b20333..9b03ce8 100644 --- a/src/private/mod.rs +++ b/src/private/mod.rs @@ -4,12 +4,3 @@ pub mod cast; pub extern crate linkme; - -#[cfg(feature = "factory")] -pub mod any_factory; - -#[cfg(feature = "factory")] -pub mod factory; - -#[cfg(feature = "factory")] -pub mod castable_factory; diff --git a/src/provider/async.rs b/src/provider/async.rs index a3db57e..3875363 100644 --- a/src/provider/async.rs +++ b/src/provider/async.rs @@ -16,21 +16,15 @@ pub enum AsyncProvidable<DIContainerT> Singleton(ThreadsafeSingletonPtr<dyn AsyncInjectable<DIContainerT>>), #[cfg(feature = "factory")] Factory( - crate::ptr::ThreadsafeFactoryPtr< - dyn crate::private::any_factory::AnyThreadsafeFactory, - >, + crate::ptr::ThreadsafeFactoryPtr<dyn crate::any_factory::AnyThreadsafeFactory>, ), #[cfg(feature = "factory")] DefaultFactory( - crate::ptr::ThreadsafeFactoryPtr< - dyn crate::private::any_factory::AnyThreadsafeFactory, - >, + crate::ptr::ThreadsafeFactoryPtr<dyn crate::any_factory::AnyThreadsafeFactory>, ), #[cfg(feature = "factory")] AsyncDefaultFactory( - crate::ptr::ThreadsafeFactoryPtr< - dyn crate::private::any_factory::AnyThreadsafeFactory, - >, + crate::ptr::ThreadsafeFactoryPtr<dyn crate::any_factory::AnyThreadsafeFactory>, ), } @@ -188,9 +182,8 @@ pub enum AsyncFactoryVariant #[cfg(feature = "factory")] pub struct AsyncFactoryProvider { - factory: crate::ptr::ThreadsafeFactoryPtr< - dyn crate::private::any_factory::AnyThreadsafeFactory, - >, + factory: + crate::ptr::ThreadsafeFactoryPtr<dyn crate::any_factory::AnyThreadsafeFactory>, variant: AsyncFactoryVariant, } @@ -199,7 +192,7 @@ impl AsyncFactoryProvider { pub fn new( factory: crate::ptr::ThreadsafeFactoryPtr< - dyn crate::private::any_factory::AnyThreadsafeFactory, + dyn crate::any_factory::AnyThreadsafeFactory, >, variant: AsyncFactoryVariant, ) -> Self @@ -307,12 +300,22 @@ mod tests #[cfg(feature = "factory")] async fn async_factory_provider_works() { - use crate::private::any_factory::AnyThreadsafeFactory; + use std::any::Any; + + use crate::any_factory::{AnyFactory, AnyThreadsafeFactory}; use crate::ptr::ThreadsafeFactoryPtr; #[derive(Debug)] struct FooFactory; + impl AnyFactory for FooFactory + { + fn as_any(&self) -> &dyn Any + { + self + } + } + impl AnyThreadsafeFactory for FooFactory {} let factory_provider = AsyncFactoryProvider::new( diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs index 5710a65..bde3be5 100644 --- a/src/provider/blocking.rs +++ b/src/provider/blocking.rs @@ -13,9 +13,9 @@ pub enum Providable<DIContainerType> Transient(TransientPtr<dyn Injectable<DIContainerType>>), Singleton(SingletonPtr<dyn Injectable<DIContainerType>>), #[cfg(feature = "factory")] - Factory(crate::ptr::FactoryPtr<dyn crate::private::any_factory::AnyFactory>), + Factory(crate::ptr::FactoryPtr<dyn crate::any_factory::AnyFactory>), #[cfg(feature = "factory")] - DefaultFactory(crate::ptr::FactoryPtr<dyn crate::private::any_factory::AnyFactory>), + DefaultFactory(crate::ptr::FactoryPtr<dyn crate::any_factory::AnyFactory>), } #[cfg_attr(test, mockall::automock)] @@ -108,7 +108,7 @@ where #[cfg(feature = "factory")] pub struct FactoryProvider { - factory: crate::ptr::FactoryPtr<dyn crate::private::any_factory::AnyFactory>, + factory: crate::ptr::FactoryPtr<dyn crate::any_factory::AnyFactory>, is_default_factory: bool, } @@ -116,7 +116,7 @@ pub struct FactoryProvider impl FactoryProvider { pub fn new( - factory: crate::ptr::FactoryPtr<dyn crate::private::any_factory::AnyFactory>, + factory: crate::ptr::FactoryPtr<dyn crate::any_factory::AnyFactory>, is_default_factory: bool, ) -> Self { @@ -196,13 +196,21 @@ mod tests #[cfg(feature = "factory")] fn factory_provider_works() { - use crate::private::any_factory::AnyFactory; + use std::any::Any; + + use crate::any_factory::AnyFactory; use crate::ptr::FactoryPtr; #[derive(Debug)] struct FooFactory; - impl AnyFactory for FooFactory {} + impl AnyFactory for FooFactory + { + fn as_any(&self) -> &dyn Any + { + self + } + } let factory_provider = FactoryProvider::new(FactoryPtr::new(FooFactory), false); let default_factory_provider = |