Voultapher / self_cell

Safe-to-use proc-macro-free self-referential structs in stable Rust.
Apache License 2.0
232 stars 14 forks source link

Support async builders? #57

Open fzyzcjy opened 1 month ago

fzyzcjy commented 1 month ago

Hi thanks for the library! I do hope the builder function can support async functions.

Context: I am considering using this package to implement returning borrowed types in https://github.com/fzyzcjy/flutter_rust_bridge. Thus the builder can be arbitrary async code.

Voultapher commented 1 month ago

Hi, thanks for reaching out. Do I understand correctly, you have a dependent construction logic that involves async calls, right?

If possible, I'd like to avoid the async coloring issue of having multiple variants of all construction functions. There are also some question about variance across await points, where I'm not sure what a sound API would look like.

Would a spawn_blocking work for your use-case?

fzyzcjy commented 1 month ago

Hi, thanks for the reply! Ok I see...

Would a spawn_blocking work for your use-case?

Well no, because https://github.com/fzyzcjy/flutter_rust_bridge needs to support arbitrary user function. If we require users to do spawn_blocking, then indeed we lose the benefits of async (e.g. not taking a whole thread).

Voultapher commented 1 month ago

Could you please outline specifically what kind of API you would need.

fzyzcjy commented 1 month ago

Sure. For example, the README example says:

impl NewStructName {
    fn new(
        owner: Owner,
        dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Dependent<'a>
    ) -> NewStructName { ... }

but now it would be great to be

impl NewStructName {
    fn new(
        owner: Owner,
        dependent_builder: impl for<'a> FnOnce(&'a Owner) -> Pin<Box<dyn Future<Output = Dependent<'a>>>> // <- support passing in async function. not necessarily have API like this.
    ) -> NewStructName { ... }

Indeed just something like https://docs.rs/ouroboros_examples/latest/ouroboros_examples/ouroboros_impl_chain/struct.Chain.html#method.new_async

Voultapher commented 1 month ago

It would need to async fn new( right?

Voultapher commented 1 month ago

Also I wonder if a minimal solution that only duplicates the new constructor is enough for a first version until people ask for more.

Voultapher commented 1 month ago

@steffahn what's you take, do we run into any variance/soundness issues with such an API?

fzyzcjy commented 1 month ago

It would need to async fn new( right?

Oh yes!

Also I wonder if a minimal solution that only duplicates the new constructor is enough for a first version until people ask for more.

Sorry not quite get it...

Btw, no worries about this issue, because if https://github.com/Voultapher/self_cell/issues/58 cannot be solved, then I unfortunately cannot use this package :( Though I think it is great and abstracts out unsafe things with well tested code!

steffahn commented 1 month ago

IIRC ouroboros has async construction APIs for a while already, so if we'd just mirror those, it might be sound (well.. or both are unsound). I haven't looked at the details myself yet.