// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace CommunityToolkit.Mvvm.Messaging.Messages; /// /// A for async request messages, which can either be used directly or through derived classes. /// /// The type of request to make. public class AsyncRequestMessage { private Task? response; /// /// Gets the message response. /// /// Thrown when is . public Task Response { get { if (!HasReceivedResponse) { ThrowInvalidOperationExceptionForNoResponseReceived(); } return this.response!; } } /// /// Gets a value indicating whether a response has already been assigned to this instance. /// public bool HasReceivedResponse { get; private set; } /// /// Replies to the current request message. /// /// The response to use to reply to the request message. /// Thrown if has already been set. public void Reply(T response) { Reply(Task.FromResult(response)); } /// /// Replies to the current request message. /// /// The response to use to reply to the request message. /// Thrown if is . /// Thrown if has already been set. public void Reply(Task response) { ArgumentNullException.ThrowIfNull(response); if (HasReceivedResponse) { ThrowInvalidOperationExceptionForDuplicateReply(); } HasReceivedResponse = true; this.response = response; } /// [Pure] [MethodImpl(MethodImplOptions.AggressiveInlining)] [EditorBrowsable(EditorBrowsableState.Never)] public TaskAwaiter GetAwaiter() { return this.Response.GetAwaiter(); } /// /// Throws an when a response is not available. /// [DoesNotReturn] private static void ThrowInvalidOperationExceptionForNoResponseReceived() { throw new InvalidOperationException("No response was received for the given request message."); } /// /// Throws an when or are called twice. /// [DoesNotReturn] private static void ThrowInvalidOperationExceptionForDuplicateReply() { throw new InvalidOperationException("A response has already been issued for the current message."); } }