Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1 @@
{"files":{"Cargo.lock":"bc7d4dfb21e31b22ba71b1b6637fcf137aac697ee3af122d0dc448910e7a7a94","Cargo.toml":"1b81ecaf960f2e58fc1a58ba533fb0d9bcc182842033ee330b1e3db3f5a87dc7","README.md":"202125e536fd43ba3ffdb28d8590497941d44fe21950251239f73dfb889a147d","license-apache-2.0":"c16f8dcf1a368b83be78d826ea23de4079fe1b4469a0ab9ee20563f37ff3d44b","license-mit":"c2cfccb812fe482101a8f04597dfc5a9991a6b2748266c47ac91b6a5aae15383","readme.md":"202125e536fd43ba3ffdb28d8590497941d44fe21950251239f73dfb889a147d","src/async.rs":"5fbd7afff0b11d687b5ea04d03b2edfedb6581aa81057e5d6fcaf85e15089817","src/async_ready.rs":"ff2941738b92cff025b2cedbe4250f2168a5e8b37ad955927b019ea72dae02ac","src/async_spawn.rs":"632b8fd0bc5157d76fa67cbc55f28084efb0d3d7634bddb9b05e4592c580eacb","src/bindings.rs":"b8f37efaf73f36ee4ad87dada1757cf790a522b7d04428d317603e8755cbba8e","src/bindings_impl.rs":"9b41306964d624dc57b631d378d8547d803c764d5ff29f8697eabed1ef53f588","src/future.rs":"738746eec764326019f07fa4eea2124c2aae32d99e43917e801b785c62793724","src/join.rs":"14139a6f0b0c9b25f0a2586190e3e0724b16dd17d300c14f6e835d0f84344767","src/lib.rs":"d986973fb214b5c652eb4ed53ff43e0b4d6e93ceaad202c720fbe148fd5ef8c4","src/waiter.rs":"bef63334d5b2ff9bfddf8a3b3d6f84cab5b703b1445d7f4f84d35311d41e7c06","src/when.rs":"295283aafb6acffe27fee8eba4700f6231bcfcd1ec742f950c8386ad275de2aa"},"package":"68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a"}

115
vendor/windows-future/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,115 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "windows-core"
version = "0.62.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-future"
version = "0.3.1"
dependencies = [
"windows-core",
"windows-link",
"windows-threading",
]
[[package]]
name = "windows-implement"
version = "0.60.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-interface"
version = "0.59.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-result"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-threading"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab47f085ad6932defa48855254c758cdd0e2f2d48e62a34118a268d8f345e118"
dependencies = [
"windows-link",
]

59
vendor/windows-future/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,59 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.82"
name = "windows-future"
version = "0.3.1"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Windows async types"
readme = "README.md"
categories = ["os::windows-apis"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/microsoft/windows-rs"
[package.metadata.docs.rs]
default-target = "x86_64-pc-windows-msvc"
targets = []
[features]
default = ["std"]
std = ["windows-core/std"]
[lib]
name = "windows_future"
path = "src/lib.rs"
[dependencies.windows-core]
version = "0.62.1"
default-features = false
[dependencies.windows-link]
version = "0.2.0"
default-features = false
[dependencies.windows-threading]
version = "0.2.0"
default-features = false
[lints.rust]
missing_unsafe_on_extern = "warn"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(windows_raw_dylib, windows_slim_errors)"]

31
vendor/windows-future/README.md vendored Normal file
View File

@@ -0,0 +1,31 @@
## Windows async types
The [windows-future](https://crates.io/crates/windows-future) crate provides stock async support for Windows APIs.
* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/master/crates/samples)
* [Releases](https://github.com/microsoft/windows-rs/releases)
Start by adding the following to your Cargo.toml file:
```toml
[dependencies.windows-future]
version = "0.3"
```
Use the Windows async types as needed:
```rust
use windows_future::*;
// This result will be available immediately.
let ready = IAsyncOperation::ready(Ok(123));
assert_eq!(ready.join().unwrap(), 123);
let ready = IAsyncOperation::spawn(|| {
// Some lengthy operation goes here...
Ok(456)
});
assert_eq!(ready.join().unwrap(), 456);
```

201
vendor/windows-future/license-apache-2.0 vendored Normal file
View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) Microsoft Corporation.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

21
vendor/windows-future/license-mit vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

31
vendor/windows-future/readme.md vendored Normal file
View File

@@ -0,0 +1,31 @@
## Windows async types
The [windows-future](https://crates.io/crates/windows-future) crate provides stock async support for Windows APIs.
* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/master/crates/samples)
* [Releases](https://github.com/microsoft/windows-rs/releases)
Start by adding the following to your Cargo.toml file:
```toml
[dependencies.windows-future]
version = "0.3"
```
Use the Windows async types as needed:
```rust
use windows_future::*;
// This result will be available immediately.
let ready = IAsyncOperation::ready(Ok(123));
assert_eq!(ready.join().unwrap(), 123);
let ready = IAsyncOperation::spawn(|| {
// Some lengthy operation goes here...
Ok(456)
});
assert_eq!(ready.join().unwrap(), 456);
```

169
vendor/windows-future/src/async.rs vendored Normal file
View File

@@ -0,0 +1,169 @@
use super::*;
// An `Async` represents a WinRT async execution object or type. There are precisely four such types:
// - IAsyncAction
// - IAsyncActionWithProgress
// - IAsyncOperation
// - IAsyncOperationWithProgress
//
// All four implementations are provided here and there is thus no need to implement this trait.
// This trait provides an abstraction over the relevant differences so that the various async
// capabilities in this crate can be reused for all implementations.
pub trait Async: Interface {
// The type of value produced on completion.
type Output: Clone;
// The type of the delegate use for completion notification.
type CompletedHandler: Interface;
// Sets the handler or callback to invoke when execution completes. This handler can only be set once.
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()>;
// Calls the given handler with the current object and status.
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus);
// Returns the value produced on completion. This should only be called when execution completes.
fn get_results(&self) -> Result<Self::Output>;
// Gets the current status of async execution. This calls `QueryInterface` so should be used sparingly.
fn status(&self) -> Result<AsyncStatus>;
// Waits for the async execution to finish and then returns the results.
fn join(&self) -> Result<Self::Output> {
if self.status()? == AsyncStatus::Started {
let (_waiter, signaler) = Waiter::new()?;
self.set_completed(move |_| {
// This is safe because the waiter will only be dropped after being signaled.
unsafe {
signaler.signal();
}
})?;
}
self.get_results()
}
// Calls `op(result)` when async execution completes.
fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<Self::Output>) + Send + 'static,
{
if self.status()? == AsyncStatus::Started {
// The `set_completed` closure is guaranteed to only be called once, like `FnOnce`, by the async pattern,
// but Rust doesn't know that so `RefCell` is used to pass `op` in to the closure.
let op = core::cell::RefCell::new(Some(op));
self.set_completed(move |sender| {
if let Some(op) = op.take() {
op(sender.get_results());
}
})?;
} else {
op(self.get_results());
}
Ok(())
}
}
impl Async for IAsyncAction {
type Output = ();
type CompletedHandler = AsyncActionCompletedHandler;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncActionCompletedHandler::new(move |sender, _| {
handler(sender.ok()?);
Ok(())
}))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<T: RuntimeType> Async for IAsyncOperation<T> {
type Output = T;
type CompletedHandler = AsyncOperationCompletedHandler<T>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncOperationCompletedHandler::new(move |sender, _| {
handler(sender.ok()?);
Ok(())
}))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<P: RuntimeType> Async for IAsyncActionWithProgress<P> {
type Output = ();
type CompletedHandler = AsyncActionWithProgressCompletedHandler<P>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncActionWithProgressCompletedHandler::new(
move |sender, _| {
handler(sender.ok()?);
Ok(())
},
))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}
impl<T: RuntimeType, P: RuntimeType> Async for IAsyncOperationWithProgress<T, P> {
type Output = T;
type CompletedHandler = AsyncOperationWithProgressCompletedHandler<T, P>;
fn set_completed<F: Fn(&Self) + Send + 'static>(&self, handler: F) -> Result<()> {
self.SetCompleted(&AsyncOperationWithProgressCompletedHandler::new(
move |sender, _| {
handler(sender.ok()?);
Ok(())
},
))
}
#[cfg(feature = "std")]
fn invoke_completed(&self, handler: &Self::CompletedHandler, status: AsyncStatus) {
_ = handler.Invoke(self, status);
}
fn get_results(&self) -> Result<Self::Output> {
self.GetResults()
}
fn status(&self) -> Result<AsyncStatus> {
self.Status()
}
}

228
vendor/windows-future/src/async_ready.rs vendored Normal file
View File

@@ -0,0 +1,228 @@
use super::*;
use std::sync::atomic::{AtomicBool, Ordering};
struct ReadyState<T: Async> {
set_completed: AtomicBool,
result: Result<T::Output>,
}
impl<T: Async> ReadyState<T> {
fn new(result: Result<T::Output>) -> Self {
Self {
set_completed: AtomicBool::new(false),
result,
}
}
fn status(&self) -> AsyncStatus {
if self.result.is_ok() {
AsyncStatus::Completed
} else {
AsyncStatus::Error
}
}
// The "Ready" implementations don't need to store the handler since the handler is invoked immediately
// but still need to confirm that `SetCompleted` is called at most once.
fn invoke_completed(&self, sender: &T, handler: Ref<T::CompletedHandler>) -> Result<()> {
if !self.set_completed.swap(true, Ordering::SeqCst) {
sender.invoke_completed(handler.ok()?, self.status());
Ok(())
} else {
Err(Error::from_hresult(HRESULT(0x80000018u32 as i32))) // E_ILLEGAL_DELEGATE_ASSIGNMENT
}
}
// The `From` implementation is not used here since we don't want to transfer any error object to the calling thread.
// That happens when `GetResults` is called.
fn error_code(&self) -> HRESULT {
match &self.result {
Ok(_) => HRESULT(0),
Err(error) => error.code(),
}
}
}
#[implement(IAsyncAction, IAsyncInfo)]
struct ReadyAction(ReadyState<IAsyncAction>);
#[implement(IAsyncOperation<T>, IAsyncInfo)]
struct ReadyOperation<T>(ReadyState<IAsyncOperation<T>>)
where
T: RuntimeType + 'static;
#[implement(IAsyncActionWithProgress<P>, IAsyncInfo)]
struct ReadyActionWithProgress<P>(ReadyState<IAsyncActionWithProgress<P>>)
where
P: RuntimeType + 'static;
#[implement(IAsyncOperationWithProgress<T, P>, IAsyncInfo)]
struct ReadyOperationWithProgress<T, P>(ReadyState<IAsyncOperationWithProgress<T, P>>)
where
T: RuntimeType + 'static,
P: RuntimeType + 'static;
impl IAsyncInfo_Impl for ReadyAction_Impl {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType> IAsyncInfo_Impl for ReadyOperation_Impl<T> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<P: RuntimeType> IAsyncInfo_Impl for ReadyActionWithProgress_Impl<P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncInfo_Impl for ReadyOperationWithProgress_Impl<T, P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl IAsyncAction_Impl for ReadyAction_Impl {
fn SetCompleted(&self, handler: Ref<AsyncActionCompletedHandler>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionCompletedHandler> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.result.clone()
}
}
impl<T: RuntimeType> IAsyncOperation_Impl<T> for ReadyOperation_Impl<T> {
fn SetCompleted(&self, handler: Ref<AsyncOperationCompletedHandler<T>>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationCompletedHandler<T>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.result.clone()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress_Impl<P> for ReadyActionWithProgress_Impl<P> {
fn SetCompleted(&self, handler: Ref<AsyncActionWithProgressCompletedHandler<P>>) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionWithProgressCompletedHandler<P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.result.clone()
}
fn SetProgress(&self, _: Ref<AsyncActionProgressHandler<P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncActionProgressHandler<P>> {
Err(Error::empty())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P>
for ReadyOperationWithProgress_Impl<T, P>
{
fn SetCompleted(
&self,
handler: Ref<AsyncOperationWithProgressCompletedHandler<T, P>>,
) -> Result<()> {
self.0.invoke_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationWithProgressCompletedHandler<T, P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.result.clone()
}
fn SetProgress(&self, _: Ref<AsyncOperationProgressHandler<T, P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncOperationProgressHandler<T, P>> {
Err(Error::empty())
}
}
impl IAsyncAction {
/// Creates an `IAsyncAction` that is immediately ready with a value.
pub fn ready(result: Result<()>) -> Self {
ReadyAction(ReadyState::new(result)).into()
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Creates an `IAsyncOperation<T>` that is immediately ready with a value.
pub fn ready(result: Result<T>) -> Self {
ReadyOperation(ReadyState::new(result)).into()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Creates an `IAsyncActionWithProgress<P>` that is immediately ready with a value.
pub fn ready(result: Result<()>) -> Self {
ReadyActionWithProgress(ReadyState::new(result)).into()
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Creates an `IAsyncOperationWithProgress<T, P>` that is immediately ready with a value.
pub fn ready(result: Result<T>) -> Self {
ReadyOperationWithProgress(ReadyState::new(result)).into()
}
}

321
vendor/windows-future/src/async_spawn.rs vendored Normal file
View File

@@ -0,0 +1,321 @@
use super::*;
use std::sync::Mutex;
struct State<T: Async> {
result: Option<Result<T::Output>>,
completed: Option<T::CompletedHandler>,
completed_assigned: bool,
}
impl<T: Async> State<T> {
fn status(&self) -> AsyncStatus {
match &self.result {
None => AsyncStatus::Started,
Some(Ok(_)) => AsyncStatus::Completed,
Some(Err(_)) => AsyncStatus::Error,
}
}
fn error_code(&self) -> HRESULT {
match &self.result {
Some(Err(error)) => error.code(),
_ => HRESULT(0),
}
}
fn get_results(&self) -> Result<T::Output> {
match &self.result {
Some(result) => result.clone(),
None => Err(Error::from_hresult(HRESULT(0x8000000Eu32 as i32))), // E_ILLEGAL_METHOD_CALL
}
}
}
struct SyncState<T: Async>(Mutex<State<T>>);
impl<T: Async> SyncState<T> {
fn new() -> Self {
Self(Mutex::new(State {
result: None,
completed: None,
completed_assigned: false,
}))
}
fn status(&self) -> AsyncStatus {
self.0.lock().unwrap().status()
}
fn error_code(&self) -> HRESULT {
self.0.lock().unwrap().error_code()
}
fn get_results(&self) -> Result<T::Output> {
self.0.lock().unwrap().get_results()
}
fn set_completed(&self, sender: &T, handler: Ref<T::CompletedHandler>) -> Result<()> {
let mut guard = self.0.lock().unwrap();
if guard.completed_assigned {
Err(Error::from_hresult(HRESULT(0x80000018u32 as i32))) // E_ILLEGAL_DELEGATE_ASSIGNMENT
} else {
guard.completed_assigned = true;
let status = guard.status();
let handler = handler.ok()?;
if status == AsyncStatus::Started {
guard.completed = Some(handler.clone());
} else {
drop(guard);
sender.invoke_completed(handler, status);
}
Ok(())
}
}
fn spawn<F>(&self, sender: &T, f: F)
where
F: FnOnce() -> Result<T::Output> + Send + 'static,
{
let result = f();
let mut guard = self.0.lock().unwrap();
debug_assert!(guard.result.is_none());
guard.result = Some(result);
let status = guard.status();
let completed = guard.completed.take();
drop(guard);
if let Some(completed) = completed {
sender.invoke_completed(&completed, status);
}
}
}
unsafe impl<T: Async> Send for SyncState<T> {}
#[implement(IAsyncAction, IAsyncInfo)]
struct Action(SyncState<IAsyncAction>);
#[implement(IAsyncOperation<T>, IAsyncInfo)]
struct Operation<T>(SyncState<IAsyncOperation<T>>)
where
T: RuntimeType + 'static;
#[implement(IAsyncActionWithProgress<P>, IAsyncInfo)]
struct ActionWithProgress<P>(SyncState<IAsyncActionWithProgress<P>>)
where
P: RuntimeType + 'static;
#[implement(IAsyncOperationWithProgress<T, P>, IAsyncInfo)]
struct OperationWithProgress<T, P>(SyncState<IAsyncOperationWithProgress<T, P>>)
where
T: RuntimeType + 'static,
P: RuntimeType + 'static;
impl IAsyncInfo_Impl for Action_Impl {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType> IAsyncInfo_Impl for Operation_Impl<T> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<P: RuntimeType> IAsyncInfo_Impl for ActionWithProgress_Impl<P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncInfo_Impl for OperationWithProgress_Impl<T, P> {
fn Id(&self) -> Result<u32> {
Ok(1)
}
fn Status(&self) -> Result<AsyncStatus> {
Ok(self.0.status())
}
fn ErrorCode(&self) -> Result<HRESULT> {
Ok(self.0.error_code())
}
fn Cancel(&self) -> Result<()> {
Ok(())
}
fn Close(&self) -> Result<()> {
Ok(())
}
}
impl IAsyncAction_Impl for Action_Impl {
fn SetCompleted(&self, handler: Ref<AsyncActionCompletedHandler>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionCompletedHandler> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.get_results()
}
}
impl<T: RuntimeType> IAsyncOperation_Impl<T> for Operation_Impl<T> {
fn SetCompleted(&self, handler: Ref<AsyncOperationCompletedHandler<T>>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationCompletedHandler<T>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.get_results()
}
}
impl<P: RuntimeType> IAsyncActionWithProgress_Impl<P> for ActionWithProgress_Impl<P> {
fn SetCompleted(&self, handler: Ref<AsyncActionWithProgressCompletedHandler<P>>) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncActionWithProgressCompletedHandler<P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<()> {
self.0.get_results()
}
fn SetProgress(&self, _: Ref<AsyncActionProgressHandler<P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncActionProgressHandler<P>> {
Err(Error::empty())
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress_Impl<T, P>
for OperationWithProgress_Impl<T, P>
{
fn SetCompleted(
&self,
handler: Ref<AsyncOperationWithProgressCompletedHandler<T, P>>,
) -> Result<()> {
self.0.set_completed(&self.as_interface(), handler)
}
fn Completed(&self) -> Result<AsyncOperationWithProgressCompletedHandler<T, P>> {
Err(Error::empty())
}
fn GetResults(&self) -> Result<T> {
self.0.get_results()
}
fn SetProgress(&self, _: Ref<AsyncOperationProgressHandler<T, P>>) -> Result<()> {
Ok(())
}
fn Progress(&self) -> Result<AsyncOperationProgressHandler<T, P>> {
Err(Error::empty())
}
}
impl IAsyncAction {
/// Creates an `IAsyncAction` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<()> + Send + 'static,
{
let object = ComObject::new(Action(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Creates an `IAsyncOperation<T>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<T> + Send + 'static,
{
let object = ComObject::new(Operation(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Creates an `IAsyncActionWithProgress<P>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<()> + Send + 'static,
{
let object = ComObject::new(ActionWithProgress(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Creates an `IAsyncOperationWithProgress<T, P>` that waits for the closure to execute on the Windows thread pool.
pub fn spawn<F>(f: F) -> Self
where
F: FnOnce() -> Result<T> + Send + 'static,
{
let object = ComObject::new(OperationWithProgress(SyncState::new()));
let interface = object.to_interface();
windows_threading::submit(move || {
object.0.spawn(&object.as_interface(), f);
});
interface
}
}

2235
vendor/windows-future/src/bindings.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
windows_link::link!("kernel32.dll" "system" fn CloseHandle(hobject : HANDLE) -> BOOL);
windows_link::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes : *const SECURITY_ATTRIBUTES, bmanualreset : BOOL, binitialstate : BOOL, lpname : PCWSTR) -> HANDLE);
windows_link::link!("kernel32.dll" "system" fn SetEvent(hevent : HANDLE) -> BOOL);
windows_link::link!("kernel32.dll" "system" fn WaitForSingleObject(hhandle : HANDLE, dwmilliseconds : u32) -> WAIT_EVENT);
pub type BOOL = i32;
pub type HANDLE = *mut core::ffi::c_void;
pub type PCWSTR = *const u16;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct SECURITY_ATTRIBUTES {
pub nLength: u32,
pub lpSecurityDescriptor: *mut core::ffi::c_void,
pub bInheritHandle: BOOL,
}
impl Default for SECURITY_ATTRIBUTES {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
pub type WAIT_EVENT = u32;

121
vendor/windows-future/src/future.rs vendored Normal file
View File

@@ -0,0 +1,121 @@
use super::*;
use std::future::{Future, IntoFuture};
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll, Waker};
// The `AsyncFuture` is needed to store some extra state needed to keep async execution up to date with possible changes
// to Rust execution context. Each async type implements `IntoFuture` rather than implementing `Future` directly so that
// this adapter may be used.
pub struct AsyncFuture<A: Async> {
// Represents the async execution and provides the virtual methods for setting up a `Completed` handler and
// calling `GetResults` when execution is completed.
inner: A,
// Provides the `Status` virtual method and saves repeated calls to `QueryInterface` during polling.
status: IAsyncInfo,
// A shared waker is needed to keep the `Completed` handler updated.
// - `Option` is used to avoid allocations for async objects that have already completed.
// - `Arc` is used to share the `Waker` with the `Completed` handler and potentially replace the `Waker`
// since we don't have the ability to replace the `Completed` handler itself.
// - `Mutex` is used to synchronize replacing the `Waker` across threads.
waker: Option<Arc<Mutex<Waker>>>,
}
impl<A: Async> AsyncFuture<A> {
fn new(inner: A) -> Self {
Self {
// All four async interfaces implement `IAsyncInfo` so this `cast` will always succeed.
status: inner.cast().unwrap(),
inner,
waker: None,
}
}
}
unsafe impl<A: Async> Send for AsyncFuture<A> {}
unsafe impl<A: Async> Sync for AsyncFuture<A> {}
impl<A: Async> Unpin for AsyncFuture<A> {}
impl<A: Async> Future for AsyncFuture<A> {
type Output = Result<A::Output>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
// A status of `Started` just means async execution is still in flight. Since WinRT async is always
// "hot start", if its not `Started` then its ready for us to call `GetResults` so we can skip all of
// the remaining set up.
if self.status.Status()? != AsyncStatus::Started {
return Poll::Ready(self.inner.get_results());
}
if let Some(shared_waker) = &self.waker {
// We have a shared waker which means we're either getting polled again or been transferred to
// another execution context. As we can't tell the difference, we need to update the shared waker
// to make sure we've got the "current" waker.
let mut guard = shared_waker.lock().unwrap();
guard.clone_from(cx.waker());
// It may be possible that the `Completed` handler acquired the lock and signaled the old waker
// before we managed to acquire the lock to update it with the current waker. We check the status
// again here just in case this happens.
if self.status.Status()? != AsyncStatus::Started {
return Poll::Ready(self.inner.get_results());
}
} else {
// If we don't have a saved waker it means this is the first time we're getting polled and should
// create the shared waker and set up a `Completed` handler.
let shared_waker = Arc::new(Mutex::new(cx.waker().clone()));
self.waker = Some(shared_waker.clone());
// Note that the handler can only be set once, which is why we need a shared waker in the first
// place. On the other hand, the handler will get called even if async execution has already
// completed, so we can just return `Pending` after setting the Completed handler.
self.inner.set_completed(move |_| {
shared_waker.lock().unwrap().wake_by_ref();
})?;
};
Poll::Pending
}
}
//
// The four `IntoFuture` trait implementations.
//
impl IntoFuture for IAsyncAction {
type Output = Result<()>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<T: RuntimeType> IntoFuture for IAsyncOperation<T> {
type Output = Result<T>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<P: RuntimeType> IntoFuture for IAsyncActionWithProgress<P> {
type Output = Result<()>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}
impl<T: RuntimeType, P: RuntimeType> IntoFuture for IAsyncOperationWithProgress<T, P> {
type Output = Result<T>;
type IntoFuture = AsyncFuture<Self>;
fn into_future(self) -> Self::IntoFuture {
AsyncFuture::new(self)
}
}

29
vendor/windows-future/src/join.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
use super::*;
impl IAsyncAction {
/// Waits for the `IAsyncAction` to finish.
pub fn join(&self) -> Result<()> {
Async::join(self)
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Waits for the `IAsyncOperation<T>` to finish.
pub fn join(&self) -> Result<T> {
Async::join(self)
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Waits for the `IAsyncActionWithProgress<P>` to finish.
pub fn join(&self) -> Result<()> {
Async::join(self)
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Waits for the `IAsyncOperationWithProgress<T, P>` to finish.
pub fn join(&self) -> Result<T> {
Async::join(self)
}
}

29
vendor/windows-future/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
#![expect(
missing_docs,
non_snake_case,
non_camel_case_types,
non_upper_case_globals,
clippy::all
)]
#![doc = include_str!("../readme.md")]
#![cfg_attr(all(not(feature = "std")), no_std)]
mod r#async;
mod bindings;
mod bindings_impl;
mod join;
mod waiter;
mod when;
pub use bindings::*;
use bindings_impl::*;
use r#async::*;
use waiter::*;
use windows_core::*;
#[cfg(feature = "std")]
mod async_ready;
#[cfg(feature = "std")]
mod async_spawn;
#[cfg(feature = "std")]
mod future;

41
vendor/windows-future/src/waiter.rs vendored Normal file
View File

@@ -0,0 +1,41 @@
use super::*;
pub struct Waiter(HANDLE);
pub struct WaiterSignaler(HANDLE);
unsafe impl Send for WaiterSignaler {}
impl Waiter {
pub fn new() -> crate::Result<(Self, WaiterSignaler)> {
unsafe {
let handle = CreateEventW(core::ptr::null(), 1, 0, core::ptr::null());
if handle.is_null() {
Err(crate::Error::from_thread())
} else {
Ok((Self(handle), WaiterSignaler(handle)))
}
}
}
}
impl WaiterSignaler {
/// # Safety
/// Signals the `Waiter`. This is unsafe because the lifetime of `WaiterSignaler` is not tied
/// to the lifetime of the `Waiter`. This is not possible in this case because the `Waiter`
/// is used to signal a WinRT async completion and the compiler doesn't know that the lifetime
/// of the delegate is bounded by the calling function.
pub unsafe fn signal(&self) {
// https://github.com/microsoft/windows-rs/pull/374#discussion_r535313344
unsafe {
SetEvent(self.0);
}
}
}
impl Drop for Waiter {
fn drop(&mut self) {
unsafe {
WaitForSingleObject(self.0, 0xFFFFFFFF);
CloseHandle(self.0);
}
}
}

41
vendor/windows-future/src/when.rs vendored Normal file
View File

@@ -0,0 +1,41 @@
use super::*;
impl IAsyncAction {
/// Calls `op(result)` when the `IAsyncAction` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<()>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<T: RuntimeType> IAsyncOperation<T> {
/// Calls `op(result)` when the `IAsyncOperation<T>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<T>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<P: RuntimeType> IAsyncActionWithProgress<P> {
/// Calls `op(result)` when the `IAsyncActionWithProgress<P>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<()>) + Send + 'static,
{
Async::when(self, op)
}
}
impl<T: RuntimeType, P: RuntimeType> IAsyncOperationWithProgress<T, P> {
/// Calls `op(result)` when the `IAsyncOperationWithProgress<T, P>` completes.
pub fn when<F>(&self, op: F) -> Result<()>
where
F: FnOnce(Result<T>) + Send + 'static,
{
Async::when(self, op)
}
}