// 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.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace FisheryLib.Utility.Diagnostics;
///
public static partial class Guard
{
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsTrue([DoesNotReturnIf(false)] bool value, [CallerArgumentExpression("value")] string name = "")
{
if (value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsTrue(name);
}
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// A message to display if is .
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsTrue([DoesNotReturnIf(false)] bool value, string name, string message)
{
if (value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsTrue(name, message);
}
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsFalse([DoesNotReturnIf(true)] bool value, [CallerArgumentExpression("value")] string name = "")
{
if (!value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsFalse(name);
}
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// A message to display if is .
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsFalse([DoesNotReturnIf(true)] bool value, string name, string message)
{
if (!value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsFalse(name, message);
}
#if NET6_0_OR_GREATER
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// A message to display if is .
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsTrue([DoesNotReturnIf(false)] bool value, string name, [InterpolatedStringHandlerArgument("value")] ref IsTrueInterpolatedStringHandler message)
{
if (value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsTrue(name, message.ToStringAndClear());
}
///
/// Asserts that the input value must be .
///
/// The input to test.
/// The name of the input parameter being tested.
/// A message to display if is .
/// Thrown if is .
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsFalse([DoesNotReturnIf(true)] bool value, string name, [InterpolatedStringHandlerArgument("value")] ref IsFalseInterpolatedStringHandler message)
{
if (!value)
{
return;
}
ThrowHelper.ThrowArgumentExceptionForIsFalse(name, message.ToStringAndClear());
}
///
/// Provides an interpolated string handler for that only performs formatting if the assert fails.
///
[EditorBrowsable(EditorBrowsableState.Never)]
[InterpolatedStringHandler]
public struct IsTrueInterpolatedStringHandler
{
///
/// The handler used to perform the formatting.
///
private StringBuilder.AppendInterpolatedStringHandler handler;
///
/// The underlying instance used by , if any.
///
private StringBuilder? builder;
///
/// Creates an instance of the handler.
///
/// The number of constant characters outside of interpolation expressions in the interpolated string.
/// The number of interpolation expressions in the interpolated string.
/// The condition passed to the method.
/// A value indicating whether formatting should proceed.
/// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly.
public IsTrueInterpolatedStringHandler(int literalLength, int formattedCount, bool condition, out bool shouldAppend)
{
if (condition)
{
this.handler = default;
this.builder = null;
shouldAppend = false;
}
else
{
StringBuilder builder = new();
this.handler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, builder);
this.builder = builder;
shouldAppend = true;
}
}
///
/// Extracts the built string from the handler.
///
internal string ToStringAndClear()
{
string message = this.builder?.ToString() ?? string.Empty;
this = default;
return message;
}
///
public void AppendLiteral(string value)
{
this.handler.AppendLiteral(value);
}
///
public void AppendFormatted(T value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(T value, string? format)
{
this.handler.AppendFormatted(value, format);
}
///
public void AppendFormatted(T value, int alignment)
{
this.handler.AppendFormatted(value, alignment);
}
///
public void AppendFormatted(T value, int alignment, string? format)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(ReadOnlySpan value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(string? value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(string? value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(object? value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
}
///
/// Provides an interpolated string handler for that only performs formatting if the assert fails.
///
[EditorBrowsable(EditorBrowsableState.Never)]
[InterpolatedStringHandler]
public struct IsFalseInterpolatedStringHandler
{
///
/// The handler used to perform the formatting.
///
private StringBuilder.AppendInterpolatedStringHandler handler;
///
/// The underlying instance used by , if any.
///
private StringBuilder? builder;
///
/// Creates an instance of the handler.
///
/// The number of constant characters outside of interpolation expressions in the interpolated string.
/// The number of interpolation expressions in the interpolated string.
/// The condition passed to the method.
/// A value indicating whether formatting should proceed.
/// This is intended to be called only by compiler-generated code. Arguments are not validated as they'd otherwise be for members intended to be used directly.
public IsFalseInterpolatedStringHandler(int literalLength, int formattedCount, bool condition, out bool shouldAppend)
{
if (!condition)
{
this.handler = default;
this.builder = null;
shouldAppend = false;
}
else
{
StringBuilder builder = new();
this.handler = new StringBuilder.AppendInterpolatedStringHandler(literalLength, formattedCount, builder);
this.builder = builder;
shouldAppend = true;
}
}
///
/// Extracts the built string from the handler.
///
internal string ToStringAndClear()
{
string message = this.builder?.ToString() ?? string.Empty;
this = default;
return message;
}
///
public void AppendLiteral(string value)
{
this.handler.AppendLiteral(value);
}
///
public void AppendFormatted(T value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(T value, string? format)
{
this.handler.AppendFormatted(value, format);
}
///
public void AppendFormatted(T value, int alignment)
{
this.handler.AppendFormatted(value, alignment);
}
///
public void AppendFormatted(T value, int alignment, string? format)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(ReadOnlySpan value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(string? value)
{
this.handler.AppendFormatted(value);
}
///
public void AppendFormatted(string? value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
///
public void AppendFormatted(object? value, int alignment = 0, string? format = null)
{
this.handler.AppendFormatted(value, alignment, format);
}
}
#endif
}