Closed audunhalland closed 2 years ago
Example of the pattern implemented, but without macros, is in https://github.com/audunhalland/rust-realworld-ioc/.
Fixed by https://github.com/audunhalland/entrait/commit/7b421df82597787a387b5024df3f483f942792f1, using a completely different and better approach.
Entrait apps have to be wrapped in
::implementation::Impl
because of specialization issues. Traits get implemented forImpl<T>
andUnimock
.Some applications need to be modular/composed of different crates, and linked together at the main crate. Imagine an app consisting of a library and a "final" app in the main crate:
In the main crate, we have some functions which want to call into entraited functions from the lib crate. But traits are not implemented for
Impl<App>
, but forImpl<AppModule>
. So we need a way to get there, without naming theApp
. We only want to mention traits. We need access to all the traits implemented byImpl<AppModule>
while still supporting unimock.So we can imagine a trait for accessing the app module:
(this cannot be a generic trait because of custom bounds on
Target
)This trait gets implemented for
Impl<App>
andUnimock
:This would work fine and we can then write things like:
But it's a lot of boilerplate to generate these impls, and I'd like to make it easier to express this relationship using a macro.
A key point is that we need to repeat all the
lib
traits as bounds forGetAppModule
, but it would be better if the lib exported its "public API" traits. It could do that by exporting a "meta trait" that inherits from all its public traits: