aboutsummaryrefslogtreecommitdiff
path: root/macros
diff options
context:
space:
mode:
Diffstat (limited to 'macros')
-rw-r--r--macros/Cargo.toml9
-rw-r--r--macros/src/injectable.rs (renamed from macros/src/injectable/mod.rs)0
-rw-r--r--macros/src/injectable/dependency.rs35
-rw-r--r--macros/src/injectable/implementation.rs57
-rw-r--r--macros/src/lib.rs4
-rw-r--r--macros/src/util.rs67
-rw-r--r--macros/src/util/error.rs48
-rw-r--r--macros/src/util/mod.rs29
8 files changed, 146 insertions, 103 deletions
diff --git a/macros/Cargo.toml b/macros/Cargo.toml
index 12f3f0b..adf4eda 100644
--- a/macros/Cargo.toml
+++ b/macros/Cargo.toml
@@ -9,7 +9,7 @@ keywords = ["di", "dependency-injection", "ioc", "inversion-of-control"]
edition = "2021"
[lib]
-proc_macro = true
+proc-macro = true
[package.metadata.docs.rs]
all-features = true
@@ -28,15 +28,20 @@ uuid = { version = "0.8", features = ["v4"] }
once_cell = "1.13.1"
thiserror = "1.0.37"
proc-macro-error = "1.0.4"
+paste = "1.0.8"
[target.'cfg(syrette_macros_logging)'.dependencies]
tracing = "0.1.37"
tracing-subscriber = "0.3.17"
-[dev_dependencies]
+[dev-dependencies]
syrette = { version = "0.5.1", path = ".." }
mockall = "0.11.4"
pretty_assertions = "1.3.0"
syn = { version = "1.0.96", features = ["full", "extra-traits"] }
utility-macros = { git = "https://git.hampusmat.com/utility-macros" }
+[lints.rust.unexpected_cfgs]
+level = "warn"
+check-cfg = ["cfg(doc_cfg)", "cfg(tarpaulin_include)", "cfg(syrette_macros_logging)"]
+
diff --git a/macros/src/injectable/mod.rs b/macros/src/injectable.rs
index 0e6ddfd..0e6ddfd 100644
--- a/macros/src/injectable/mod.rs
+++ b/macros/src/injectable.rs
diff --git a/macros/src/injectable/dependency.rs b/macros/src/injectable/dependency.rs
index 8e22f21..30c156f 100644
--- a/macros/src/injectable/dependency.rs
+++ b/macros/src/injectable/dependency.rs
@@ -6,23 +6,6 @@ use crate::injectable::named_attr_input::NamedAttrInput;
use crate::util::error::diagnostic_error_enum;
use crate::util::syn_path::SynPathExt;
-/// Interface for a dependency of a `Injectable`.
-#[cfg_attr(test, mockall::automock)]
-pub trait IDependency: Sized
-{
- /// Build a new `Dependency` from a argument in a constructor method.
- fn build(ctor_method_arg: &FnArg) -> Result<Self, DependencyError>;
-
- /// Returns the interface type.
- fn get_interface(&self) -> &Type;
-
- /// Returns the pointer type identity.
- fn get_ptr(&self) -> &Ident;
-
- /// Returns optional name of the dependency.
- fn get_name(&self) -> &Option<LitStr>;
-}
-
/// Representation of a dependency of a injectable type.
///
/// Found as a argument in the constructor method of a `Injectable`.
@@ -34,9 +17,11 @@ pub struct Dependency
name: Option<LitStr>,
}
-impl IDependency for Dependency
+#[cfg_attr(test, mockall::automock)]
+impl Dependency
{
- fn build(ctor_method_arg: &FnArg) -> Result<Self, DependencyError>
+ /// Build a new `Dependency` from a argument in a constructor method.
+ pub fn build(ctor_method_arg: &FnArg) -> Result<Self, DependencyError>
{
let typed_ctor_method_arg = match ctor_method_arg {
FnArg::Typed(typed_arg) => Ok(typed_arg),
@@ -116,17 +101,23 @@ impl IDependency for Dependency
})
}
- fn get_interface(&self) -> &Type
+ /// Returns the dependency's interface type.
+ #[allow(dead_code)] // Mock function is never used
+ pub fn get_interface(&self) -> &Type
{
&self.interface
}
- fn get_ptr(&self) -> &Ident
+ /// Returns the dependency's pointer type name.
+ #[allow(dead_code)] // Mock function is never used
+ pub fn get_ptr(&self) -> &Ident
{
&self.ptr
}
- fn get_name(&self) -> &Option<LitStr>
+ /// Returns the dependency's name.
+ #[allow(dead_code)] // Mock function is never used
+ pub fn get_name(&self) -> &Option<LitStr>
{
&self.name
}
diff --git a/macros/src/injectable/implementation.rs b/macros/src/injectable/implementation.rs
index a98d1ce..a67b4a3 100644
--- a/macros/src/injectable/implementation.rs
+++ b/macros/src/injectable/implementation.rs
@@ -16,7 +16,7 @@ use syn::{
Type,
};
-use crate::injectable::dependency::{DependencyError, IDependency};
+use crate::injectable::dependency::DependencyError;
use crate::util::error::diagnostic_error_enum;
use crate::util::item_impl::find_impl_method_by_name_mut;
use crate::util::string::camelcase_to_snakecase;
@@ -28,19 +28,22 @@ use crate::util::syn_ext::{
MethodTurbofishExt,
};
use crate::util::syn_path::{syn_path, SynPathExt};
+use crate::util::use_double;
+
+use_double!(crate::injectable::dependency::Dependency);
const DI_CONTAINER_VAR_NAME: &str = "di_container";
const DEPENDENCY_HISTORY_VAR_NAME: &str = "dependency_history";
-pub struct InjectableImpl<Dep: IDependency>
+pub struct InjectableImpl
{
- dependencies: Vec<Dep>,
+ dependencies: Vec<Dependency>,
original_impl: ItemImpl,
constructor_method: ImplItemMethod,
}
-impl<Dep: IDependency> InjectableImpl<Dep>
+impl InjectableImpl
{
#[cfg(not(tarpaulin_include))]
pub fn new(
@@ -334,7 +337,7 @@ impl<Dep: IDependency> InjectableImpl<Dep>
}
fn create_get_dep_method_calls(
- dependencies: &[Dep],
+ dependencies: &[Dependency],
is_async: bool,
di_container_var: &Ident,
dependency_history_var: &Ident,
@@ -353,7 +356,7 @@ impl<Dep: IDependency> InjectableImpl<Dep>
.collect()
}
- fn create_binding_options(dependency: &Dep) -> Expr
+ fn create_binding_options(dependency: &Dependency) -> Expr
{
let binding_options_new = Expr::Call(ExprCall::new(
Expr::Path(ExprPath::new(syn_path!(
@@ -373,7 +376,7 @@ impl<Dep: IDependency> InjectableImpl<Dep>
}
fn create_single_get_dep_method_call(
- dependency: &Dep,
+ dependency: &Dependency,
is_async: bool,
di_container_var: &Ident,
dependency_history_var: &Ident,
@@ -432,12 +435,12 @@ impl<Dep: IDependency> InjectableImpl<Dep>
fn build_dependencies(
ctor_method: &ImplItemMethod,
- ) -> Result<Vec<Dep>, DependencyError>
+ ) -> Result<Vec<Dependency>, DependencyError>
{
let ctor_method_args = &ctor_method.sig.inputs;
let dependencies_result: Result<Vec<_>, _> =
- ctor_method_args.iter().map(Dep::build).collect();
+ ctor_method_args.iter().map(Dependency::build).collect();
let deps = dependencies_result?;
@@ -582,7 +585,7 @@ mod tests
};
use super::*;
- use crate::injectable::dependency::MockIDependency;
+ use crate::injectable::dependency::MockDependency;
use crate::injectable::named_attr_input::NamedAttrInput;
use crate::test_utils::{
create_path,
@@ -650,14 +653,14 @@ mod tests
let _lock = get_lock(&TEST_MUTEX);
- let build_context = MockIDependency::build_context();
+ let build_context = MockDependency::build_context();
build_context
.expect()
- .returning(|_| Ok(MockIDependency::new()));
+ .returning(|_| Ok(MockDependency::new()));
- let dependencies = InjectableImpl::<MockIDependency>::build_dependencies(&method)
- .expect("Expected Ok");
+ let dependencies =
+ InjectableImpl::build_dependencies(&method).expect("Expected Ok");
assert_eq!(dependencies.len(), 2);
}
@@ -719,15 +722,15 @@ mod tests
let _lock = get_lock(&TEST_MUTEX);
- let build_context = MockIDependency::build_context();
+ let build_context = MockDependency::build_context();
build_context
.expect()
- .returning(|_| Ok(MockIDependency::new()))
+ .returning(|_| Ok(MockDependency::new()))
.times(2);
- let dependencies = InjectableImpl::<MockIDependency>::build_dependencies(&method)
- .expect("Expected Ok");
+ let dependencies =
+ InjectableImpl::build_dependencies(&method).expect("Expected Ok");
assert_eq!(dependencies.len(), 2);
}
@@ -804,7 +807,7 @@ mod tests
},
};
- InjectableImpl::<MockIDependency>::remove_method_argument_attrs(&mut method);
+ InjectableImpl::remove_method_argument_attrs(&mut method);
assert_eq!(
method.sig.inputs.first().unwrap().clone(),
@@ -830,7 +833,7 @@ mod tests
#[test]
fn can_create_single_get_dep_method_call()
{
- let mut mock_dependency = MockIDependency::new();
+ let mut mock_dependency = MockDependency::new();
mock_dependency
.expect_get_interface()
@@ -848,7 +851,7 @@ mod tests
let di_container_var_ident = format_ident!("{}", DI_CONTAINER_VAR_NAME);
let dep_history_var_ident = format_ident!("{}", DEPENDENCY_HISTORY_VAR_NAME);
- let output = InjectableImpl::<MockIDependency>::create_single_get_dep_method_call(
+ let output = InjectableImpl::create_single_get_dep_method_call(
&mock_dependency,
false,
&format_ident!("{}", DI_CONTAINER_VAR_NAME),
@@ -880,7 +883,7 @@ mod tests
#[test]
fn can_create_single_get_dep_method_call_with_name()
{
- let mut mock_dependency = MockIDependency::new();
+ let mut mock_dependency = MockDependency::new();
mock_dependency
.expect_get_interface()
@@ -900,7 +903,7 @@ mod tests
let di_container_var_ident = format_ident!("{}", DI_CONTAINER_VAR_NAME);
let dep_history_var_ident = format_ident!("{}", DEPENDENCY_HISTORY_VAR_NAME);
- let output = InjectableImpl::<MockIDependency>::create_single_get_dep_method_call(
+ let output = InjectableImpl::create_single_get_dep_method_call(
&mock_dependency,
false,
&format_ident!("{}", DI_CONTAINER_VAR_NAME),
@@ -932,7 +935,7 @@ mod tests
#[test]
fn can_create_single_get_dep_method_call_async()
{
- let mut mock_dependency = MockIDependency::new();
+ let mut mock_dependency = MockDependency::new();
mock_dependency
.expect_get_interface()
@@ -950,7 +953,7 @@ mod tests
let di_container_var_ident = format_ident!("{}", DI_CONTAINER_VAR_NAME);
let dep_history_var_ident = format_ident!("{}", DEPENDENCY_HISTORY_VAR_NAME);
- let output = InjectableImpl::<MockIDependency>::create_single_get_dep_method_call(
+ let output = InjectableImpl::create_single_get_dep_method_call(
&mock_dependency,
true,
&format_ident!("{}", DI_CONTAINER_VAR_NAME),
@@ -983,7 +986,7 @@ mod tests
#[test]
fn can_create_single_get_dep_method_call_async_with_name()
{
- let mut mock_dependency = MockIDependency::new();
+ let mut mock_dependency = MockDependency::new();
mock_dependency
.expect_get_interface()
@@ -1003,7 +1006,7 @@ mod tests
let di_container_var_ident = format_ident!("{}", DI_CONTAINER_VAR_NAME);
let dep_history_var_ident = format_ident!("{}", DEPENDENCY_HISTORY_VAR_NAME);
- let output = InjectableImpl::<MockIDependency>::create_single_get_dep_method_call(
+ let output = InjectableImpl::create_single_get_dep_method_call(
&mock_dependency,
true,
&format_ident!("{}", DI_CONTAINER_VAR_NAME),
diff --git a/macros/src/lib.rs b/macros/src/lib.rs
index e55e23f..b9b6ea5 100644
--- a/macros/src/lib.rs
+++ b/macros/src/lib.rs
@@ -23,7 +23,6 @@ use syn::{
use crate::caster::generate_caster;
use crate::declare_interface_args::DeclareInterfaceArgs;
-use crate::injectable::dependency::Dependency;
use crate::injectable::dummy::expand_dummy_blocking_impl;
use crate::injectable::implementation::{InjectableImpl, InjectableImplError};
use crate::injectable::macro_args::InjectableMacroArgs;
@@ -255,8 +254,7 @@ pub fn injectable(args_stream: TokenStream, input_stream: TokenStream) -> TokenS
);
}
- let injectable_impl =
- InjectableImpl::<Dependency>::new(item_impl, &constructor).unwrap_or_abort();
+ let injectable_impl = InjectableImpl::new(item_impl, &constructor).unwrap_or_abort();
injectable_impl.validate(is_async).unwrap_or_abort();
diff --git a/macros/src/util.rs b/macros/src/util.rs
new file mode 100644
index 0000000..3557896
--- /dev/null
+++ b/macros/src/util.rs
@@ -0,0 +1,67 @@
+pub mod error;
+pub mod item_impl;
+pub mod iterator_ext;
+pub mod string;
+pub mod syn_ext;
+pub mod syn_path;
+pub mod tokens;
+
+macro_rules! to_option {
+ ($($tokens: tt)+) => {
+ Some($($tokens)+)
+ };
+
+ () => {
+ None
+ };
+}
+
+macro_rules! or {
+ (($($tokens: tt)+) else ($($default: tt)*)) => {
+ $($tokens)*
+ };
+
+ (() else ($($default: tt)*)) => {
+ $($default)*
+ };
+}
+
+/// Imports the specified item, prepending 'Mock' to the item identifier if the `test`
+/// configuration option is set.
+///
+/// # Examples
+/// ```ignore
+/// use_double!(crate::dependency_history::DependencyHistory);
+/// ```
+/// <br>
+///
+/// Expands to the following when `cfg(not(test))`
+/// ```ignore
+/// use crate::dependency_history::DependencyHistory;
+/// ```
+/// <br>
+///
+/// Expands to the following when `cfg(test)`
+/// ```ignore
+/// use crate::dependency_history::MockDependencyHistory as DependencyHistory;
+/// ```
+macro_rules! use_double {
+ ($([$($part: ident),*])? $item_path_part: ident :: $($next_part: tt)+) => {
+ use_double!(
+ [$($($part,)*)? $item_path_part]
+ $($next_part)+
+ );
+ };
+
+ ([$($part: ident),*] $item_path_part: ident) => {
+ #[cfg(not(test))]
+ use $($part::)* $item_path_part;
+
+ ::paste::paste! {
+ #[cfg(test)]
+ use $($part::)* [<Mock $item_path_part>] as $item_path_part;
+ }
+ };
+}
+
+pub(crate) use {or, to_option, use_double};
diff --git a/macros/src/util/error.rs b/macros/src/util/error.rs
index d068661..b9f67c4 100644
--- a/macros/src/util/error.rs
+++ b/macros/src/util/error.rs
@@ -1,3 +1,6 @@
+use proc_macro2::Span;
+use proc_macro_error::Diagnostic;
+
/// Used to create a error enum that converts into a [`Diagnostic`].
///
/// [`Diagnostic`]: proc_macro_error::Diagnostic
@@ -30,22 +33,17 @@ macro_rules! diagnostic_error_enum {
#[must_use]
fn from(err: $name) -> Self
{
- let (error, span, notes, helps, errs, source): (
- String,
- ::proc_macro2::Span,
- Vec<(String, ::proc_macro2::Span)>,
- Vec<(String, ::proc_macro2::Span)>,
- Vec<(String, ::proc_macro2::Span)>,
- Option<::proc_macro_error::Diagnostic>
- ) = match err {
+ use $crate::util::error::DiagnosticErrorVariantInfo;
+
+ let DiagnosticErrorVariantInfo {
+ error, span, notes, helps, errs, source
+ } = match err {
$(
- $name::$variant {
- $($variant_field),*
- } => {
- (
- format!($($error)*),
- $error_span,
- vec![$(
+ $name::$variant { $($variant_field),* } => {
+ DiagnosticErrorVariantInfo {
+ error: format!($($error)*),
+ span: $error_span,
+ notes: vec![$(
(
format!($($note)*),
$crate::util::or!(
@@ -54,7 +52,7 @@ macro_rules! diagnostic_error_enum {
)
)
),*],
- vec![$(
+ helps: vec![$(
(
format!($($help)*),
$crate::util::or!(
@@ -63,7 +61,7 @@ macro_rules! diagnostic_error_enum {
)
)
),*],
- vec![$(
+ errs: vec![$(
(
format!($($err)*),
$crate::util::or!(
@@ -72,8 +70,8 @@ macro_rules! diagnostic_error_enum {
)
)
),*],
- $crate::util::to_option!($($source.into())?)
- )
+ source: $crate::util::to_option!($($source.into())?)
+ }
}
),*
};
@@ -109,8 +107,18 @@ macro_rules! diagnostic_error_enum {
diagnostic
}
}
-
};
}
+/// Used by [`diagnostic_error_enum`].
+pub struct DiagnosticErrorVariantInfo
+{
+ pub error: String,
+ pub span: Span,
+ pub notes: Vec<(String, Span)>,
+ pub helps: Vec<(String, Span)>,
+ pub errs: Vec<(String, Span)>,
+ pub source: Option<Diagnostic>,
+}
+
pub(crate) use diagnostic_error_enum;
diff --git a/macros/src/util/mod.rs b/macros/src/util/mod.rs
deleted file mode 100644
index 7ab2185..0000000
--- a/macros/src/util/mod.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-pub mod error;
-pub mod item_impl;
-pub mod iterator_ext;
-pub mod string;
-pub mod syn_ext;
-pub mod syn_path;
-pub mod tokens;
-
-macro_rules! to_option {
- ($($tokens: tt)+) => {
- Some($($tokens)+)
- };
-
- () => {
- None
- };
-}
-
-macro_rules! or {
- (($($tokens: tt)+) else ($($default: tt)*)) => {
- $($tokens)*
- };
-
- (() else ($($default: tt)*)) => {
- $($default)*
- };
-}
-
-pub(crate) use {or, to_option};