I was able to move data into the context of a closure that would return my application state, but that’s no longer possible because now the closure must implement Fn instead of FnOnce. This was possible in 0.13, is this by design?
This is what my code used to look like:
impl State {
fn new(db_connection: rusqlite::Connection, args: clap::ArgMatches) -> (Self, iced::Task<Message>) {
...
}
pub fn main() -> iced::Result {
let matches = clap::Command::new("App").arg(...).get_matches();
let connection = get_db_connection();
// execute some queries in the DB that are required to initialize my iced::Settings
return iced::application(...).run_with(|| State::new(connection, clap_matches));
}
That’s what doesn’t work anymore (or maybe that one does because counter is Copy, but let’s assume it isn’t) because that closure will be a FnOnce and not a Fn which is now the required type.
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnOnce`
--> src/main.rs:709:30
|
709 | return iced::application(move || Vimini::new(matches, db_connection), Vimini::update, Vimini::view)
| ----------------- ^^^^^^^------------------------------------
| | | |
| | | closure is `FnOnce` because it moves the variable `matches` out of its environment
| | this closure implements `FnOnce`, not `Fn`
| | the requirement to implement `Fn` derives from here
| required by a bound introduced by this call
I can always clone the data but it still looks like a step back from what was possible before.
Ah, that’s a nice hack, I wanted a closure that would take the value from an Option the first time and panic the other times but I wasn’t clever enough to code it, I always ended up with my closure implementing FnMut instead of FnOnce. Thanks for this.
As to the motivation, I wonder if the new daemon type of program maybe needs to call boot multiple times.