Conversation
Today in This Should Be Easy But in #Rust It Apparently Isn't: how do I encapsulate the widget initialization (without triggering E0515) in this example, so it becomes reusable?

https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=f31dd1ecf5530b11e301bb19af85b0fa
3
2
0

@buherator check out Box::new(T).

If you want mutation etc you may want to also check out RefCell and mayb3 even UnsafeCell!

[If I'm reading your PG example correctly]

1
0
0

@buherator I’m not really sure what you mean by incapsulate the initialisation. Maybe showing the code you are getting an error from would help.

1
0
0
@alphastrata Thanks! I'll probably end a up a solution like that but still wonder if this can be achieved without Box/refcounts (should've added to the question)?
0
0
0
@edmcbane Imagine that initialization is more complex and I want to provide a library that hides that complexity, exposing something like setup_widget() and deinit_all().

You can see an E0515 here (among other things), but I intentionally refrained from providing my attempts because I suspect there is a completely different Rust pattern for similar cases:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=0f4a1eeba2c33741fafc059d717e87bb

It's important that I can't touch Session or Widget as they are provided by a library (with FFI).
0
0
0

@buherator@infosec.place Can you be more specific about what you want to do?

1
0
0
@addison From a different branch of this convo:

"Imagine that initialization is more complex and I want to provide a library that hides that complexity, exposing something like setup_widget() and deinit_all()."

https://infosec.place/notice/B3RIRrdtPQog3eUc2y
1
0
0

@buherator@infosec.place Yeah, you'll need some indirection here. You can't move session while it is borrowed. Alternatively, you can keep the widgets in the session (e.g., in a vec or smth) and only offer (mutably) borrowed access to the widgets by an ID or something. It just depends on what's appropriate for your use case; presumably, widgets should always be deinitialized when the session is, so the session should "own" the widgets.

1
0
0
@addison Thanks, that makes sense, but I can't touch Session as it comes from a dependency. There is definitely a lifetime issue here too (esp. because the actual tree of objects goes ~5 levels deep).

I think the root of my Q is if there is a way to create a "will" for Rust functions/scopes that would say "after my death my caller will inherit all that I own (so please don't free shit up)"?
1
0
0

@buherator@infosec.place Then it's time for an Rc<RefCell<Session>> instead of a lifetime (or Arc<RwLock<...>> if asynchronous). Just be careful to avoid cycles. :)

2
0
0

@buherator@infosec.place For deinit_all you definitely need some wrapper object keeping track of the widgets, but that should be compatible here. If the session can die independently, use Weak instead of Rc/Arc.

0
0
1
@addison Thanks, that's in line with @alphastrata's suggestion and the advice I got afk.

I'm quite new to Rust and it's strange that something as simple as moving a couple of lines of code into a function (I'm still considering a macro actually) can require this much consideration, but I guess this is the price we pay for stability.
2
0
0

@buherator@infosec.place Yeah, Rust will really force you to be careful here. In other languages, you might initialize the widget with a pointer, but then if you move the value, the pointer is invalid. Similarly with concurrent access to the session object. You're prohibited from constructions which are potentially faulty.

0
0
1

@buherator Self referential structs, in most of the codebases I work in on would be considered a bit of an anti pattern -- for UI, a lot of the ... 'opinions' of Rust become 'tricky'.

Keep at it :)

1
0
1
@alphastrata The root of the issue is that the library I'm using is not originally in/for Rust, so such best practices simply don't exist in their world...
1
0
0

@buherator Iced, and egui are probably the two gotos for all my projects (unless you need 3d in which case I'd go with Bevy or Godot).

The web ppl like Dioxus, but I dunno anything about electron or the web.

0
0
0