Tuple as inline arguments for callback function

Just interesting,
I can set this tuple result from state function in one line for callback function?

    pub fn connect_activate(&self, callback: impl Fn(Option<i32>, bool, bool) + 'static) {
        self.gobject.connect_activate(move |this, _| {
            let (position, is_pinned, is_selected) = state(this);
            callback(position, is_pinned, is_selected)
        });
    }

Mean something like that:

//..
callback(state(this))
//..

Here is entire code.

On nightly you can do something like this:

#![feature(fn_traits)]

fn state() -> (Option<i32>, bool, bool) {
    (None, true, false)
}

fn foo(callback: impl Fn(Option<i32>, bool, bool)) {
    callback.call(state());
}

fn main() {
    foo(|a, b, c| println!("{a:?} {b} {c}"));
}

Playground.

2 Likes

If you don't want to use nightly, this would, however, require you to change the signature of callback() to accept such a tuple instead of individual arguments.

2 Likes

Yes, same thoughts to change resulting type, but hope some sugar exist
I'm beginner, so not understand the nightly features yet, but thanks for option!

If your callback signature is fixed, you can define an extension trait:

trait FnExt {
    fn my_call(&self, arg: (Option<i32>, bool, bool));
}

impl<F: Fn(Option<i32>, bool, bool)> FnExt for F {
    fn my_call(&self, (a, b, c): (Option<i32>, bool, bool)) { self(a, b, c) }
}

fn foo(callback: impl Fn(Option<i32>, bool, bool)) {
    callback.my_call(state());
}
2 Likes

Now that I think of it ... only callback arity needs to be fixed, types can be generic:

trait FnExt3<A, B, C> {
    type R;
    fn my_call(&self, arg: (A, B, C)) -> Self::R;
}

impl<A, B, C, R, F: Fn(A, B, C) -> R> FnExt3<A, B, C> for F {
    type R = R;
    fn my_call(&self, (a, b, c): (A, B, C)) -> R { self(a, b, c) }
}

... and you can define a bunch of these similarly to what std does for e.g. impl Eq for (...)

2 Likes