audunhalland / entrait

Loosely coupled Rust application design made easy
86 stars 3 forks source link

Generics in app state #28

Closed wackazong closed 1 year ago

wackazong commented 1 year ago

I am continuing to work with your crate, it's really useful.

One thing where I am stuck: I have an object from an external crate that comes in as an &mut imp SomeTrait. It is a storage interface. Is there any way I can store this in the application state? I tried, but I get into trouble with Send and Sync traits.

audunhalland commented 1 year ago

Sorry for late reply, I was on vacation when the bug was filed and the notification slipped me by.

I agree that this scenario could be a challenge. The app in Impl<App> as I envisioned it is intended to be an owner of application state or "configuration", like storing the address to the database you connect to. I haven't tested putting lifetime constrained types in Impl, or &mut stuff, I admit I never thought of this usecase!

It sounds a little tricky. Send/Sync bounds are inserted everywhere to make this work with tokio work-stealing, with currently no way to opt out IIRC.

What I would do to test a proof of concept would be to write a small test app, apply the normal #[entrait] annotations, and then do expand macro recursively (w/rust-analyzer) on all these sites and replace your app with the desugared code. Then try to modifiy the bounds and see if you can somehow make it compile. If it's possible, we could look at new entrait options to modify code generation to suit your usecase.

wackazong commented 1 year ago

I gave up on this for now, as I can just pass the &mut impl SomeTrait around as an additional variable. Except for elegance this does the job just as well.

What I do is use Impl to store some mutexed variables, which works nicely out of the box.