Yesterday I started a second thread in regard to what I try to achieve in the end, which also contains a minimal example of my working solution (which still has the problem I try to overcome).
However, it seems, this problem can't be solved, currently.
However, there is one form of negative reasoning built in to the trait system already: No conflicting implementations allowed.
Thank you! This is great example, and I bookmarked it for when I need this kind of permission handling.
I considered a sealed trait at the beginning, but I think this can't be used here.
Basically, we have this:
PluginSys
, which holds all plugins (which hold their data)
- Plugins have an
execute
method, which takes &mut PluginSys
as argument
UsePlugin<PluginN>
is implemented for PluginSystem
, so plugins can use UsePlugin::get_plugin_mut
to get other plugins
- This indirection is required because
PluginSystem
is generated by a macro, so plugins don't know anything about PluginSystem
, or the other plugins it contains (they only know the types of the plugins they depend on, which they can access by requiring UsePlugin<T>
on PluginSys
)
UsePlugin<T>
needs to be implemented for all plugins, so it's not possible to forbid UsePlugin<Plugin1>
when PluginSys
executes Plugin1
(if I'm not missing anything)
My solution was to create a NewType Plugin1Sys
for Plugin1
, and then implement UsePlugin<T>
on Plugin1Sys
for all plugins but Plugin1
.
PluginSys
would then pass Plugin1Sys<&mut PluginSys>
to Plugin1::execute
(which introduced the problematic lifetime this thread initially was about).
Would there be a benefit of using your approach on Plugin1Sys
?
Maybe I could use this to prevent the end-user (which has full access to the code the macro generates in the end-users crate) to implement UsePlugin<Plugin1>
for Plugin1Sys
.
Thank you, @Rustaceous!
you can use a generic lifetime on the trait itself
Wouldn't that mean, that this lifetime is as long as the plugin exists?
Because the PluginNSys
NewTypes only exist as long as the call to Plugin::execute
lasts.
You could also use single-method traits like this one and group them together using a supertrait.
I think you Playground refers to your first tip, and I'm not very sure how I'd use your second tip in this context. With the above information, do you still think, this could work here?