diff options
| author | HampusM <hampus@hampusmat.com> | 2022-08-03 11:50:59 +0200 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2022-08-03 11:50:59 +0200 | 
| commit | c33cf02c9a6fffc6149fd7b59c63ad0d15d61432 (patch) | |
| tree | f72edf77d7f10de85012fa869ecd01e8b161c435 | |
| parent | 3db388dd567fbabb6a88ee7100de65442089c3f1 (diff) | |
refactor: add Cargo feature for preventing circular dependencies
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | macros/Cargo.toml | 1 | ||||
| -rw-r--r-- | macros/src/injectable_impl.rs | 40 | 
4 files changed, 28 insertions, 17 deletions
@@ -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" @@ -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  | 
