I'm working on a higher-level crate called fluent-fallback that is meant to provide a user-facing abstraction over low-level APIs that Fluent (localization system) works with.
And now I'm designing the async version. The async version is mean to provide analogous API except that it's async and the input method is returning Iterator over futures - this allows the FluentBundle to be generated asynchronously using async I/O.
I struggle to design the lifetimes to properly handle the async case. Here's a minimized testcase I came up with: Rust Playground
Can someone help me squeeze the right lifetime bounds for this API?
Well, it's possible to get it to compile (Playground), but I'm not so sure it's going to do what you want.
It's also of pretty daunting complexity if you are going to need to maintain and debug it. I would strive finding an alternative and simpler design if at all possible. I would only ever consider keeping something like this as utter last resort, if I really can't find any better solution. For example, if you want to work with reference types because you are afraid that copying a few strings around would hurt performance to much, I would urge you to take the problem from the other end. Eg. get a working version as simple as possible, disregarding all performance considerations and then measure it. Start optimizing from there if and only if it's necessary.
In any case, you won't be allowed to call on_change while format_values is being awaited.
Probably easiest to throw it in a diff to see what I changed.
Ah, thank you! So it was just about binding the lifetime in the closure!
Yeah, I agree its not optimal. I'll try to simplify it, but also expect that as Rust advances, we'll get more robust generators and async iterators and it'll all be easier to write