use super::*; use std::sync::atomic::{AtomicBool, Ordering}; struct ReadyState { set_completed: AtomicBool, result: Result, } impl ReadyState { fn new(result: Result) -> 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) -> 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); #[implement(IAsyncOperation, IAsyncInfo)] struct ReadyOperation(ReadyState>) where T: RuntimeType + 'static; #[implement(IAsyncActionWithProgress

, IAsyncInfo)] struct ReadyActionWithProgress

(ReadyState>) where P: RuntimeType + 'static; #[implement(IAsyncOperationWithProgress, IAsyncInfo)] struct ReadyOperationWithProgress(ReadyState>) where T: RuntimeType + 'static, P: RuntimeType + 'static; impl IAsyncInfo_Impl for ReadyAction_Impl { fn Id(&self) -> Result { Ok(1) } fn Status(&self) -> Result { Ok(self.0.status()) } fn ErrorCode(&self) -> Result { Ok(self.0.error_code()) } fn Cancel(&self) -> Result<()> { Ok(()) } fn Close(&self) -> Result<()> { Ok(()) } } impl IAsyncInfo_Impl for ReadyOperation_Impl { fn Id(&self) -> Result { Ok(1) } fn Status(&self) -> Result { Ok(self.0.status()) } fn ErrorCode(&self) -> Result { Ok(self.0.error_code()) } fn Cancel(&self) -> Result<()> { Ok(()) } fn Close(&self) -> Result<()> { Ok(()) } } impl IAsyncInfo_Impl for ReadyActionWithProgress_Impl

{ fn Id(&self) -> Result { Ok(1) } fn Status(&self) -> Result { Ok(self.0.status()) } fn ErrorCode(&self) -> Result { Ok(self.0.error_code()) } fn Cancel(&self) -> Result<()> { Ok(()) } fn Close(&self) -> Result<()> { Ok(()) } } impl IAsyncInfo_Impl for ReadyOperationWithProgress_Impl { fn Id(&self) -> Result { Ok(1) } fn Status(&self) -> Result { Ok(self.0.status()) } fn ErrorCode(&self) -> Result { 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) -> Result<()> { self.0.invoke_completed(&self.as_interface(), handler) } fn Completed(&self) -> Result { Err(Error::empty()) } fn GetResults(&self) -> Result<()> { self.0.result.clone() } } impl IAsyncOperation_Impl for ReadyOperation_Impl { fn SetCompleted(&self, handler: Ref>) -> Result<()> { self.0.invoke_completed(&self.as_interface(), handler) } fn Completed(&self) -> Result> { Err(Error::empty()) } fn GetResults(&self) -> Result { self.0.result.clone() } } impl IAsyncActionWithProgress_Impl

for ReadyActionWithProgress_Impl

{ fn SetCompleted(&self, handler: Ref>) -> Result<()> { self.0.invoke_completed(&self.as_interface(), handler) } fn Completed(&self) -> Result> { Err(Error::empty()) } fn GetResults(&self) -> Result<()> { self.0.result.clone() } fn SetProgress(&self, _: Ref>) -> Result<()> { Ok(()) } fn Progress(&self) -> Result> { Err(Error::empty()) } } impl IAsyncOperationWithProgress_Impl for ReadyOperationWithProgress_Impl { fn SetCompleted( &self, handler: Ref>, ) -> Result<()> { self.0.invoke_completed(&self.as_interface(), handler) } fn Completed(&self) -> Result> { Err(Error::empty()) } fn GetResults(&self) -> Result { self.0.result.clone() } fn SetProgress(&self, _: Ref>) -> Result<()> { Ok(()) } fn Progress(&self) -> Result> { 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 IAsyncOperation { /// Creates an `IAsyncOperation` that is immediately ready with a value. pub fn ready(result: Result) -> Self { ReadyOperation(ReadyState::new(result)).into() } } impl IAsyncActionWithProgress

{ /// Creates an `IAsyncActionWithProgress

` that is immediately ready with a value. pub fn ready(result: Result<()>) -> Self { ReadyActionWithProgress(ReadyState::new(result)).into() } } impl IAsyncOperationWithProgress { /// Creates an `IAsyncOperationWithProgress` that is immediately ready with a value. pub fn ready(result: Result) -> Self { ReadyOperationWithProgress(ReadyState::new(result)).into() } }