// 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.");
}
}