From c33cf02c9a6fffc6149fd7b59c63ad0d15d61432 Mon Sep 17 00:00:00 2001 From: HampusM Date: Wed, 3 Aug 2022 11:50:59 +0200 Subject: refactor: add Cargo feature for preventing circular dependencies --- Cargo.toml | 2 ++ README.md | 2 +- macros/Cargo.toml | 1 + macros/src/injectable_impl.rs | 40 ++++++++++++++++++++++++---------------- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ac1cee9..3fd751a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,9 @@ edition = "2021" all-features = true [features] +default = ["prevent-circular"] factory = ["syrette_macros/factory"] +prevent-circular = ["syrette_macros/prevent-circular"] [[example]] name = "factory" diff --git a/README.md b/README.md index c244345..50dc5ac 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,10 @@ From the [syrette Wikipedia article](https://en.wikipedia.org/wiki/Syrette). - Enforces the use of interface traits - Supports generic implementations & generic interface traits - Binding singletons -- Detection and prevention of circular dependencies ## Optional features - `factory`. Binding factories (Rust nightly required) +- `prevent-circular`. Detection and prevention of circular dependencies. (Enabled by default) To use these features, you must [enable it in Cargo](https://doc.rust-lang.org/cargo/reference/features.html#dependency-features). diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 36cc8eb..73f583d 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -16,6 +16,7 @@ all-features = true [features] factory = [] +prevent-circular = [] [dependencies] syn = { version = "1.0.96", features = ["full"] } diff --git a/macros/src/injectable_impl.rs b/macros/src/injectable_impl.rs index 3bd7113..29e0094 100644 --- a/macros/src/injectable_impl.rs +++ b/macros/src/injectable_impl.rs @@ -66,6 +66,29 @@ impl InjectableImpl } }; + let maybe_prevent_circular_deps = if cfg!(feature = "prevent-circular") { + quote! { + if dependency_history.contains(&self_type_name) { + dependency_history.push(self_type_name); + + return Err( + report!(ResolveError) + .attach_printable(format!( + "Detected circular dependencies. {}", + syrette::dependency_trace::create_dependency_trace( + dependency_history.as_slice(), + self_type_name + ) + )) + ); + } + + dependency_history.push(self_type_name); + } + } else { + quote! {} + }; + quote! { #original_impl @@ -83,22 +106,7 @@ impl InjectableImpl let self_type_name = std::any::type_name::<#self_type>(); - if dependency_history.contains(&self_type_name) { - dependency_history.push(self_type_name); - - return Err( - report!(ResolveError) - .attach_printable(format!( - "Detected circular dependencies. {}", - syrette::dependency_trace::create_dependency_trace( - dependency_history.as_slice(), - self_type_name - ) - )) - ); - } - - dependency_history.push(self_type_name); + #maybe_prevent_circular_deps return Ok(syrette::ptr::TransientPtr::new(Self::new( #(#get_dependencies -- cgit v1.2.3-18-g5258