microsoft / windows-rs

Rust for Windows
https://kennykerr.ca/rust-getting-started/
Apache License 2.0
10.43k stars 493 forks source link

Support closures as delegates #332

Open kennykerr opened 4 years ago

kennykerr commented 4 years ago

Rust/WinRT doesn't yet automatically bind a lambda/closure to a delegate parameter. Today you need to create the delegate yourself. It looks something like this:

list.current_item_changed(TypedEventHandler::new(|_sender, _args| {
    // do stuff here
    Ok(())
}))?;

In the future you should be able to write simply:

list.current_item_changed(|_sender, _args| {
    // do stuff here
    Ok(())
})?;

The difficulty is in somehow specializing the winrt::Param generic for delegates to automatically create a WinRT delegate as needed while still supporting delegate objects for pass-through.

Alternatively, we could just use FnMut as the generic param for delegates. That would probably provide the best experience in most cases, but would suffer from "over-wrapping" delegate objects that are merely being passed through.

rylev commented 4 years ago

This might not be possible to do since conceptually we need to ensure methods which take delegates are generic over some type which is either a delegate which takes some type that implements FnMut or another type which also implements the same FnMut trait. I believe this would require higher-kinded types since the generic delegate type is itself generic over some type.

kennykerr commented 4 years ago

Challenge accepted. 🤜

kennykerr commented 2 years ago

Given that passing a closure is by far the most common scenario, we could make that the default and provide a XxxWithDelegate "overload" for when you absolutely must pass an existing delegate object.

kennykerr commented 4 months ago

Closing this old issue - doesn't seem to be much demand for such API support. Let me know if you have thoughts to the contrary. 😊

kennykerr commented 1 month ago

Reopening as there's been some renewed interest in WinRT API support.