windows-rs
windows-rs copied to clipboard
Support for creating collections
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.
This depends on #81
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.
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.
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>
.
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.
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++.
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.
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
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:
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.
You should be able to pass a reference as follows:
let strings: IIterable<HSTRING> = ...
SomeMethod(&strings)?;
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.
- https://microsoft.github.io/windows-docs-rs/doc/windows/Storage/FileProperties/struct.BasicProperties.html#method.RetrievePropertiesAsync
- https://microsoft.github.io/windows-docs-rs/doc/windows/Storage/FileProperties/struct.BasicProperties.html#method.SavePropertiesAsync
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?
Not ETA, but I'm working on component authoring support at the moment and collection support is an important part of that.
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.
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! 🥲