Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for creating collections #91

Closed
kennykerr opened this issue Apr 28, 2020 · 15 comments · Fixed by #2353
Closed

Support for creating collections #91

kennykerr opened this issue Apr 28, 2020 · 15 comments · Fixed by #2353
Labels
enhancement New feature or request

Comments

@kennykerr
Copy link
Collaborator

Many APIs assume the caller will provide a collection of values. This should integrate with winrt::Param to allow regular Rust collections and iterators to bind to WinRT input parameters of WinRT collection types.

@kennykerr
Copy link
Collaborator Author

This depends on #81

@kennykerr kennykerr added this to the 0.8 milestone Nov 19, 2020
@rookboom
Copy link

rookboom commented Jan 12, 2021

Many APIs assume the caller will provide a collection of values. This should integrate with winrt::Param to allow regular Rust collections and iterators to bind to WinRT input parameters of WinRT collection types.

Is there any workaround for this? I am trying to create a windows::ai::machine_learning::TensorFloat. It has a create2 constructor function which requires a Param<IIterable<i64>> as input .

Ideally I would like to call TensorFloat::create2([1,2,3]).
If I could create an IVector v somehow, I could maybe do something like TensorFloat::create2(v.get_view().into()) but the single_threaded_vector function does not seem to be available in Rust.

@kennykerr
Copy link
Collaborator Author

kennykerr commented Jan 12, 2021

As a workaround, you can create a WinRT component with C++/WinRT that creates and returns the collection and then call that from Rust. You can even just have a component that returns an empty collection that you can then populate using Rust.

@riverar
Copy link
Collaborator

riverar commented Jun 9, 2021

As a workaround, you can create a WinRT component with C++/WinRT that creates and returns the collection and then call that from Rust. [...]

Hey @kennykerr, is this still a current workaround? Just hit this myself, needing an IVector<IRandomAccessStream>.

@kennykerr
Copy link
Collaborator Author

Yes, this is still blocked on #81 where I need to add support to implement generic interfaces. Right now, the implement macro will only let you implement non-generic interfaces. I hope to get to this soon.

@GPeye
Copy link

GPeye commented Aug 28, 2022

Hey @kennykerr , is this still blocked? #81 is now closed. Granted, it did spin off a few other issues. I just need some way to pass an IIterable of HSTRINGs from Rust to wintrt. I'm hoping a year of progress has yielded at least a work around at this point that doesn't involve C++.

@tangp3
Copy link

tangp3 commented Sep 2, 2022

Had the same issue,, I need to create IVector in rust in order to make it into ::windows::core::IntoParam<'a, IIterable<T>> form as it's required by windows crate api. I didn't find a single_threaded_vector or similar ones to use in rust.
@kennykerr, I am relatively new to rust, curious how does below help if creating a collection isn't supported yet?

You can even just have a component that returns an empty collection that you can then populate using Rust.

@kennykerr
Copy link
Collaborator Author

Yes, there's been some progress here. You can now implement the collection interfaces in Rust. This issue remains open because I haven't yet published a stock implementation, such as cppwinrt's single_threaded_vector, that would simplify this considerably, but you can use the implement macro to define your own. The tests provide a few examples here:

https://github.com/microsoft/windows-rs/tree/master/crates/tests/implement/tests

@tim-weis
Copy link
Contributor

I am relatively new to rust, curious how does below help if creating a collection isn't supported yet?

You can even just have a component that returns an empty collection that you can then populate using Rust.

@tangp3 The core idea behind this revolves around the fact that the Windows Runtime provides a language-agnostic ABI. A Windows Runtime Components can be authored using any of the supported WinRT programming languages, and consumed from code written in any of the supported languages.

The workaround described takes advantage of this by creating a Windows Runtime Component using C++/WinRT that exposes a factory method (e.g. a static member of a runtimeclass) that returns an empty IVector. The implementation is as simple as returning a default-constructed single_threaded_vector, with all the implementation details well hidden behind the function template.

Rust code can now import this Windows Runtime Component and use its functionality to obtain an empty IVector whenever it needs one. With an IVector in hand, all methods and properties are instantly available to Rust (such as inserting, appending, or removing elements). What the workaround ultimately boils down to is enabling use of C++/WinRT's mature library code from Rust, with the Windows Runtime's ABI acting as mediator.

Authoring support for Windows Runtime Types in Rust has come a long way, and the implement macro makes much of this workaround moot. The exception being that there is no library code in the windows crate yet that provides an IVector implementation, so the burden of implementing the interface is still on the developer. That's pretty much what's behind this statement:

This issue remains open because I haven't yet published a stock implementation, such as cppwinrt's single_threaded_vector, that would simplify this considerably

@reedHam
Copy link

reedHam commented Feb 17, 2023

Any update on this I'm having some issues trying to pass input params that match these traits.

::windows::core::InParam<super::super::Foundation::Collections::IIterable<::windows::core::HSTRING>>

Using the example from https://github.com/microsoft/windows-rs/blob/master/crates/tests/implement/tests/into_impl.rs

I was able to get an instance of

Iterable<HSTRING>

But I'm too dumb to implement the into InParam trait.

@kennykerr
Copy link
Collaborator Author

kennykerr commented Feb 17, 2023

You should be able to pass a reference as follows:

let strings: IIterable<HSTRING> = ...
SomeMethod(&strings)?;

@reedHam
Copy link

reedHam commented Feb 18, 2023

I end up with a compiler error.

the trait `std::convert::From<&Iterable<windows::core::HSTRING>>` is not implemented for `&windows::Foundation::Collections::IIterable<windows::core::HSTRING>`

I'm trying to call these two functions.

Since I will have to implement IIterable<IKeyValuePair<HSTRING, IInspectable>> as well for the saving function this may just be too advanced for me.

Is there any ETA on the collections being completed?

@kennykerr
Copy link
Collaborator Author

Not ETA, but I'm working on component authoring support at the moment and collection support is an important part of that.

@kennykerr
Copy link
Collaborator Author

Good news, I was able to address some longstanding perquisites and started working on stock collections. For example, you will soon be able to write something like this:

let able = IIterable::<i32>::try_from(vec![1, 2, 3])?;

I should have these stock collections available soon.

@kennykerr
Copy link
Collaborator Author

kennykerr commented Feb 24, 2023

That was a busy week and concludes my work on WinRT collections for the time being. #2346, #2350, and #2353 cover the majority of cases where you'd need to create a collection to pass some data to an API. And these implementations are entirely thread safe!

I'll leave the implementation of mutable WinRT collections for the time being as that is far less important outside of component authors and even then, APIs should prefer immutable collections. If you need to implement IVector or IMap, just have a look at the stock implementations for inspiration.

Sorry it took so long, but that was a mountain of work! 🥲

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants