aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-08-15 23:15:19 +0200
committerHampusM <hampus@hampusmat.com>2023-08-15 23:18:59 +0200
commite381ae3b8649de47ba46925e402946658ac16d20 (patch)
tree32ecc7e4592f25d43dc1e76399d3fffae3272e1e
parent9423d67efb161d9a94a7ab6c5899c6bc7ecaee7c (diff)
fix!: make the factory macro not change its input
BREAKING CHANGE: The factory macro no longer - Changes the return type to be inside of a TransientPtr - Adds Send + Sync bounds when the threadsafe or the async flag is set - Changes the return type be inside of a BoxFuture when the async flag is set
-rw-r--r--examples/async-factory/main.rs4
-rw-r--r--examples/async/interfaces/food.rs3
-rw-r--r--examples/factory/interfaces/user.rs4
-rw-r--r--macros/src/factory/type_alias.rs12
-rw-r--r--macros/src/lib.rs45
-rw-r--r--src/di_container/asynchronous/binding/builder.rs25
-rw-r--r--src/di_container/asynchronous/mod.rs6
-rw-r--r--src/di_container/blocking/binding/builder.rs7
-rw-r--r--src/di_container/blocking/mod.rs48
9 files changed, 62 insertions, 92 deletions
diff --git a/examples/async-factory/main.rs b/examples/async-factory/main.rs
index 76efb2f..d368a32 100644
--- a/examples/async-factory/main.rs
+++ b/examples/async-factory/main.rs
@@ -6,6 +6,7 @@ use std::time::Duration;
use anyhow::Result;
use syrette::di_container::asynchronous::prelude::*;
+use syrette::future::BoxFuture;
use syrette::ptr::TransientPtr;
use syrette::{declare_default_factory, factory};
use tokio::time::sleep;
@@ -16,7 +17,8 @@ trait IFoo: Send + Sync
}
#[factory(async = true)]
-type IFooFactory = dyn Fn(i32) -> dyn IFoo;
+type IFooFactory =
+ dyn Fn(i32) -> BoxFuture<'static, TransientPtr<dyn IFoo>> + Send + Sync;
struct Foo
{
diff --git a/examples/async/interfaces/food.rs b/examples/async/interfaces/food.rs
index e85519b..9d88083 100644
--- a/examples/async/interfaces/food.rs
+++ b/examples/async/interfaces/food.rs
@@ -1,4 +1,5 @@
use syrette::factory;
+use syrette::ptr::TransientPtr;
pub trait IFood: Send + Sync
{
@@ -6,4 +7,4 @@ pub trait IFood: Send + Sync
}
#[factory(threadsafe = true)]
-pub type IFoodFactory = dyn Fn() -> dyn IFood;
+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 75fbc87..aafd0cb 100644
--- a/examples/factory/interfaces/user.rs
+++ b/examples/factory/interfaces/user.rs
@@ -1,4 +1,5 @@
use syrette::factory;
+use syrette::ptr::TransientPtr;
pub trait IUser
{
@@ -8,4 +9,5 @@ pub trait IUser
}
#[factory]
-pub type IUserFactory = dyn Fn(&'static str, &'static str, &'static str) -> dyn IUser;
+pub type IUserFactory =
+ dyn Fn(&'static str, &'static str, &'static str) -> TransientPtr<dyn IUser>;
diff --git a/macros/src/factory/type_alias.rs b/macros/src/factory/type_alias.rs
index 790175b..fafcd54 100644
--- a/macros/src/factory/type_alias.rs
+++ b/macros/src/factory/type_alias.rs
@@ -1,7 +1,6 @@
use quote::ToTokens;
use syn::parse::{Parse, ParseStream};
-use syn::punctuated::Punctuated;
-use syn::{parse2, ItemType, Token, Type};
+use syn::{parse2, ItemType};
use crate::fn_trait::FnTrait;
@@ -9,8 +8,6 @@ pub struct FactoryTypeAlias
{
pub type_alias: ItemType,
pub factory_interface: FnTrait,
- pub arg_types: Punctuated<Type, Token![,]>,
- pub return_type: Type,
}
impl Parse for FactoryTypeAlias
@@ -27,8 +24,6 @@ impl Parse for FactoryTypeAlias
Ok(Self {
type_alias,
factory_interface: aliased_fn_trait.clone(),
- arg_types: aliased_fn_trait.inputs,
- return_type: aliased_fn_trait.output,
})
}
}
@@ -39,8 +34,9 @@ mod tests
use std::error::Error;
use quote::{format_ident, quote};
+ use syn::punctuated::Punctuated;
use syn::token::And;
- use syn::TypeReference;
+ use syn::{Type, TypeReference};
use super::*;
use crate::test_utils;
@@ -55,7 +51,7 @@ mod tests
let factory_type_alias = parse2::<FactoryTypeAlias>(input_args)?;
assert_eq!(
- factory_type_alias.arg_types,
+ 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"), &[])
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index 41001ae..c179b95 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -248,15 +248,12 @@ pub fn injectable(args_stream: TokenStream, input_stream: TokenStream) -> TokenS
/// Makes a type alias usable as a factory interface.
///
-/// The return type is automatically put inside of a [`TransientPtr`].
-///
/// # Arguments
/// * (Zero or more) Flags. Like `a = true, b = false`
///
/// # Flags
/// - `threadsafe` - Mark as threadsafe.
-/// - `async` - Mark as async. Infers the `threadsafe` flag. The return type is
-/// automatically put inside of a pinned boxed future.
+/// - `async` - Mark as async. Infers the `threadsafe` flag.
///
/// # Examples
/// ```
@@ -277,7 +274,7 @@ pub fn injectable(args_stream: TokenStream, input_stream: TokenStream) -> TokenS
/// # impl IConfigurator for Configurator {}
/// #
/// #[factory]
-/// type IConfiguratorFactory = dyn Fn(Vec<String>) -> dyn IConfigurator;
+/// type IConfiguratorFactory = dyn Fn(Vec<String>) -> TransientPtr<dyn IConfigurator>;
/// ```
///
/// [`TransientPtr`]: https://docs.rs/syrette/latest/syrette/ptr/type.TransientPtr.html
@@ -288,16 +285,11 @@ pub fn injectable(args_stream: TokenStream, input_stream: TokenStream) -> TokenS
#[proc_macro_attribute]
pub fn factory(args_stream: TokenStream, input_stream: TokenStream) -> TokenStream
{
- use quote::ToTokens;
- use syn::{parse2, parse_str};
-
use crate::factory::build_declare_interfaces::build_declare_factory_interfaces;
use crate::factory::macro_args::FactoryMacroArgs;
use crate::factory::type_alias::FactoryTypeAlias;
- let input_stream: proc_macro2::TokenStream = input_stream.into();
-
- set_dummy(input_stream.clone());
+ set_dummy(input_stream.clone().into());
let FactoryMacroArgs { flags } = parse(args_stream).unwrap_or_abort();
@@ -318,34 +310,9 @@ pub fn factory(args_stream: TokenStream, input_stream: TokenStream) -> TokenStre
}
let FactoryTypeAlias {
- mut type_alias,
- mut factory_interface,
- arg_types: _,
- return_type: _,
- } = parse2(input_stream).unwrap_or_abort();
-
- let output = factory_interface.output.clone();
-
- factory_interface.output = parse(
- if is_async {
- quote! {
- syrette::future::BoxFuture<'static, syrette::ptr::TransientPtr<#output>>
- }
- } else {
- quote! {
- syrette::ptr::TransientPtr<#output>
- }
- }
- .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());
- }
-
- type_alias.ty = Box::new(Type::Verbatim(factory_interface.to_token_stream()));
+ type_alias,
+ factory_interface,
+ } = parse(input_stream).unwrap_or_abort();
let decl_interfaces =
build_declare_factory_interfaces(&factory_interface, is_threadsafe);
diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs
index 45597e8..306d196 100644
--- a/src/di_container/asynchronous/binding/builder.rs
+++ b/src/di_container/asynchronous/binding/builder.rs
@@ -147,7 +147,7 @@ where
/// # impl Foo for Bar {}
/// #
/// # #[factory(threadsafe = true)]
- /// # type FooFactory = dyn Fn(i32, String) -> dyn Foo;
+ /// # type FooFactory = dyn Fn(i32, String) -> TransientPtr<dyn Foo> + Send + Sync;
/// #
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn Error>>
@@ -226,6 +226,7 @@ where
/// # use syrette::{factory};
/// # use syrette::di_container::asynchronous::prelude::*;
/// # use syrette::ptr::TransientPtr;
+ /// # use syrette::future::BoxFuture;
/// #
/// # trait Foo: Send + Sync {}
/// #
@@ -238,7 +239,10 @@ where
/// # impl Foo for Bar {}
/// #
/// # #[factory(async = true)]
- /// # type FooFactory = dyn Fn(i32, String) -> dyn Foo;
+ /// # type FooFactory = dyn Fn(i32, String) -> BoxFuture<
+ /// # 'static,
+ /// # TransientPtr<dyn Foo>
+ /// # > + Send + Sync;
/// #
/// # #[tokio::main]
/// # async fn main() -> Result<(), Box<dyn Error>>
@@ -546,10 +550,12 @@ mod tests
#[factory(threadsafe = true)]
type IUserManagerFactory = dyn Fn(
- String,
- i32,
- subjects_async::Number,
- ) -> dyn subjects_async::IUserManager;
+ String,
+ i32,
+ subjects_async::Number,
+ ) -> TransientPtr<dyn subjects_async::IUserManager>
+ + Send
+ + Sync;
let mut di_container_mock =
mocks::async_di_container::MockAsyncDIContainer::new();
@@ -590,12 +596,17 @@ mod tests
#[cfg(feature = "factory")]
async fn can_bind_to_async_factory() -> Result<(), Box<dyn Error>>
{
+ use crate::future::BoxFuture;
use crate::ptr::TransientPtr;
use crate::test_utils::async_closure;
use crate::{self as syrette, factory};
+ #[rustfmt::skip]
#[factory(async = true)]
- type IUserManagerFactory = dyn Fn(String) -> dyn subjects_async::IUserManager;
+ type IUserManagerFactory = dyn Fn(String) -> BoxFuture<
+ 'static,
+ TransientPtr<dyn subjects_async::IUserManager>
+ > + Send + Sync;
let mut di_container_mock =
mocks::async_di_container::MockAsyncDIContainer::new();
diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous/mod.rs
index 927f549..d330f4a 100644
--- a/src/di_container/asynchronous/mod.rs
+++ b/src/di_container/asynchronous/mod.rs
@@ -657,7 +657,8 @@ mod tests
use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory;
#[crate::factory(threadsafe = true)]
- type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager;
+ type IUserManagerFactory =
+ dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync;
let di_container = AsyncDIContainer::new();
@@ -752,7 +753,8 @@ mod tests
use crate::private::castable_factory::threadsafe::ThreadsafeCastableFactory;
#[crate::factory(threadsafe = true)]
- type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager;
+ type IUserManagerFactory =
+ dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync;
let di_container = AsyncDIContainer::new();
diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs
index 991961c..91855f5 100644
--- a/src/di_container/blocking/binding/builder.rs
+++ b/src/di_container/blocking/binding/builder.rs
@@ -151,10 +151,10 @@ where
/// # impl ICustomer for Customer {}
/// #
/// # #[factory]
- /// # type ICustomerFactory = dyn Fn(String, u32) -> dyn ICustomer;
+ /// # type ICustomerFactory = dyn Fn(String, u32) -> TransientPtr<dyn ICustomer>;
/// #
/// # #[factory]
- /// # type ICustomerIDFactory = dyn Fn(u32) -> dyn ICustomerID;
+ /// # type ICustomerIDFactory = dyn Fn(u32) -> TransientPtr<dyn ICustomerID>;
/// #
/// # fn main() -> Result<(), Box<dyn Error>>
/// # {
@@ -354,7 +354,8 @@ mod tests
use crate::ptr::TransientPtr;
#[factory]
- type IUserManagerFactory = dyn Fn(i32, String) -> dyn subjects::IUserManager;
+ type IUserManagerFactory =
+ dyn Fn(i32, String) -> TransientPtr<dyn subjects::IUserManager>;
let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs
index 5781583..aa89aad 100644
--- a/src/di_container/blocking/mod.rs
+++ b/src/di_container/blocking/mod.rs
@@ -493,28 +493,22 @@ mod tests
}
}
- type FactoryFunc = dyn Fn<
- (std::rc::Rc<DIContainer>,),
- Output = Box<
- dyn Fn<(Vec<i128>,), Output = crate::ptr::TransientPtr<dyn IUserManager>>,
- >,
- >;
-
use crate as syrette;
#[crate::factory]
- type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager;
+ type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>;
let di_container = DIContainer::new();
- let factory_func: &'static FactoryFunc = &|_: Rc<DIContainer>| {
- Box::new(move |users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ let factory_func: &dyn Fn(Rc<DIContainer>) -> Box<IUserManagerFactory> =
+ &|_: Rc<DIContainer>| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- user_manager
- })
- };
+ user_manager
+ })
+ };
let mut mock_provider = mocks::blocking_provider::MockProvider::new();
@@ -577,28 +571,22 @@ mod tests
}
}
- type FactoryFunc = dyn Fn<
- (std::rc::Rc<DIContainer>,),
- Output = Box<
- dyn Fn<(Vec<i128>,), Output = crate::ptr::TransientPtr<dyn IUserManager>>,
- >,
- >;
-
use crate as syrette;
#[crate::factory]
- type IUserManagerFactory = dyn Fn(Vec<i128>) -> dyn IUserManager;
+ type IUserManagerFactory = dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager>;
let di_container = DIContainer::new();
- let factory_func: &'static FactoryFunc = &|_: Rc<DIContainer>| {
- Box::new(move |users| {
- let user_manager: TransientPtr<dyn IUserManager> =
- TransientPtr::new(UserManager::new(users));
+ let factory_func: &dyn Fn(Rc<DIContainer>) -> Box<IUserManagerFactory> =
+ &|_: Rc<DIContainer>| {
+ Box::new(move |users| {
+ let user_manager: TransientPtr<dyn IUserManager> =
+ TransientPtr::new(UserManager::new(users));
- user_manager
- })
- };
+ user_manager
+ })
+ };
let mut mock_provider = mocks::blocking_provider::MockProvider::new();