diff --git a/AGENTS.md b/AGENTS.md
index df13986f..cf25ed3c 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -13,3 +13,5 @@ Read ./ai-plans/AGENTS.md for details on how to write plans.
## Here is Your Space
If you encounter something worth noting while you are working on this code base, write it down here in this section. Once you are finished, I will discuss it with you, and we can decide where to put your notes.
+
+- The source exporter used to merge `Check.*.cs` files in `DirectoryInfo.GetFiles` order, which is filesystem-dependent and unordered on APFS, so adding source files could reshuffle the entire generated single file. `SourceFileMerger` now sorts the file list with `OrderBy(f => f.Name, StringComparer.Ordinal)`, making the output deterministic. The regeneration that shipped with the sign guards contains the resulting one-time reshuffle; future diffs will only show actual content changes.
diff --git a/Light.GuardClauses.SingleFile.cs b/Light.GuardClauses.SingleFile.cs
index cda3893c..9d1d245f 100644
--- a/Light.GuardClauses.SingleFile.cs
+++ b/Light.GuardClauses.SingleFile.cs
@@ -54,159 +54,6 @@ namespace Light.GuardClauses
// ReSharper disable once RedundantTypeDeclarationBody -- required for Source Code Transformation
internal static class Check
{
- ///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
- ///
- /// The string to be checked.
- /// The other string must end with.
- /// One of the enumeration values that specifies the rules for the search (optional). The default value is .
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not end with .
- /// Thrown when or is null.
- /// Thrown when is not a valid value.
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType = StringComparison.CurrentCulture, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.MustNotBeNull(parameterName, message).EndsWith(value, comparisonType))
- {
- Throw.StringDoesNotEndWith(parameter, value, comparisonType, parameterName, message);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
- ///
- /// The string to be checked.
- /// The other string must end with.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- ///
- /// Your custom exception thrown when does not end with ,
- /// or when is null,
- /// or when is null.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, [NotNull, ValidatedNotNull] Func exceptionFactory)
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
- if (parameter is null || value is null || !parameter.EndsWith(value))
- {
- Throw.CustomException(exceptionFactory, parameter, value!);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the string ends with the specified value, or otherwise throws a .
- ///
- /// The string to be checked.
- /// The other string must end with.
- /// One of the enumeration values that specifies the rules for the search.
- /// The delegate that creates your custom exception. , , and are passed to this delegate.
- ///
- /// Your custom exception thrown when does not end with ,
- /// or when is null,
- /// or when is null.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; value:null => halt; exceptionFactory:null => halt")]
- public static string MustEndWith([NotNull, ValidatedNotNull] this string? parameter, [NotNull, ValidatedNotNull] string value, StringComparison comparisonType, [NotNull, ValidatedNotNull] Func exceptionFactory)
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract -- caller might have NRTs turned off
- if (parameter is null || value is null || !parameter.EndsWith(value, comparisonType))
- {
- Throw.CustomException(exceptionFactory, parameter, value!, comparisonType);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the specified URI has the "http" or "https" scheme, or otherwise throws an .
- ///
- /// The URI to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when uses a different scheme than "http" or "https".
- /// Thrown when is relative and thus has no scheme.
- /// Thrown when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeHttpOrHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.MustBeAbsoluteUri(parameterName, message).Scheme.Equals("https") == false && parameter.Scheme.Equals("http") == false)
- {
- Throw.UriMustHaveOneSchemeOf(parameter, ["https", "http"], parameterName, message);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the specified URI has the "http" or "https" scheme, or otherwise throws your custom exception.
- ///
- /// The URI to be checked.
- /// The delegate that creates the exception to be thrown. is passed to this delegate.
- /// Your custom exception thrown when uses a different scheme than "http" or "https", or when is a relative URI, or when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeHttpOrHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory)
- {
- if (parameter.MustBeAbsoluteUri(exceptionFactory).Scheme.Equals("https") == false && parameter.Scheme.Equals("http") == false)
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that is within the specified range, or otherwise throws an .
- ///
- /// The type of the parameter to be checked.
- /// The parameter to be checked.
- /// The range where must be in-between.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is not within .
- /// Thrown when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where T : IComparable
- {
- if (!range.IsValueWithinRange(parameter.MustNotBeNullReference(parameterName, message)))
- {
- Throw.MustBeInRange(parameter, range, parameterName, message);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that is within the specified range, or otherwise throws your custom exception.
- ///
- /// The parameter to be checked.
- /// The range where must be in-between.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when is not within , or when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, Func, Exception> exceptionFactory)
- where T : IComparable
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || !range.IsValueWithinRange(parameter))
- {
- Throw.CustomException(exceptionFactory, parameter!, range);
- }
-
- return parameter;
- }
-
///
/// Checks if the specified type derives from the other type. Internally, this method uses
/// by default so that constructed generic types and their corresponding generic type definitions are regarded as equal.
@@ -260,120 +107,104 @@ public static bool DerivesFrom([NotNull][ValidatedNotNull] this Type type, [NotN
}
///
- /// Checks if the specified character is a letter.
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsLetter(this char character) => char.IsLetter(character);
- ///
- /// Ensures that the string is shorter than or equal to the specified length, or otherwise throws a .
+ /// Checks if the specified strings are equal, using the given comparison rules.
///
- /// The string to be checked.
- /// The length that the string must be shorter than or equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when has a length greater than .
- /// Thrown when is null.
+ /// The first string to compare.
+ /// The second string to compare.
+ /// One of the enumeration values that specifies the rules for the comparison.
+ /// True if the two strings are considered equal, else false.
+ /// Thrown when is no valid enum value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeShorterThanOrEqualTo([NotNull][ValidatedNotNull] this string? parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static bool Equals(this string? @string, string? value, StringComparisonType comparisonType)
{
- if (parameter.MustNotBeNull(parameterName, message).Length > length)
+ if ((int)comparisonType < 6)
{
- Throw.StringNotShorterThanOrEqualTo(parameter, length, parameterName, message);
+ return string.Equals(@string, value, (StringComparison)comparisonType);
}
- return parameter;
+ switch (comparisonType)
+ {
+ case StringComparisonType.OrdinalIgnoreWhiteSpace:
+ return @string.EqualsOrdinalIgnoreWhiteSpace(value);
+ case StringComparisonType.OrdinalIgnoreCaseIgnoreWhiteSpace:
+ return @string.EqualsOrdinalIgnoreCaseIgnoreWhiteSpace(value);
+ default:
+ Throw.EnumValueNotDefined(comparisonType, nameof(comparisonType));
+ return false;
+ }
}
///
- /// Ensures that the string is shorter than or equal to the specified length, or otherwise throws your custom exception.
+ /// Checks if the type implements the specified interface type. Internally, this method uses
+ /// so that constructed generic types and their corresponding generic type definitions are regarded as equal.
///
- /// The string to be checked.
- /// The length that the string must be shorter than or equal to.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when is null or when it has a length greater than .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeShorterThanOrEqualTo([NotNull][ValidatedNotNull] this string? parameter, int length, Func exceptionFactory)
+ /// The type to be checked.
+ /// The interface type that should implement.
+ /// Thrown when or is null.
+ [ContractAnnotation("type:null => halt; interfaceType:null => halt")]
+ public static bool Implements([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type interfaceType)
{
- if (parameter is null || parameter.Length > length)
+ type.MustNotBeNull();
+ interfaceType.MustNotBeNull();
+ var implementedInterfaces = type.GetInterfaces();
+ for (var i = 0; i < implementedInterfaces.Length; ++i)
{
- Throw.CustomException(exceptionFactory, parameter, length);
+ if (interfaceType.IsEquivalentTypeTo(implementedInterfaces[i]))
+ {
+ return true;
+ }
}
- return parameter;
+ return false;
}
///
- /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws an .
+ /// Checks if the type implements the specified interface type. This overload uses the specified
+ /// to compare the interface types.
///
- /// The span to be checked.
- /// The length value that the span must be shorter than or equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is longer than .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeShorterThanOrEqualTo(this Span parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ /// The type to be checked.
+ /// The interface type that should implement.
+ /// The equality comparer used to compare the interface types.
+ /// Thrown when , or , or is null.
+ [ContractAnnotation("type:null => halt; interfaceType:null => halt; typeComparer:null => halt")]
+ public static bool Implements([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type interfaceType, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer)
{
- ((ReadOnlySpan)parameter).MustBeShorterThanOrEqualTo(length, parameterName, message);
- return parameter;
+ type.MustNotBeNull();
+ interfaceType.MustNotBeNull();
+ typeComparer.MustNotBeNull();
+ var implementedInterfaces = type.GetInterfaces();
+ for (var i = 0; i < implementedInterfaces.Length; ++i)
+ {
+ if (typeComparer.Equals(implementedInterfaces[i], interfaceType))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
///
- /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws your custom exception.
+ /// Checks if the given type derives from the specified base class or interface type. Internally, this method uses
+ /// so that constructed generic types and their corresponding generic type definitions are regarded as equal.
///
- /// The span to be checked.
- /// The length value that the span must be shorter than or equal to.
- /// The delegate that creates your custom exception. and are passed to it.
- /// Your custom exception thrown when is longer than .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeShorterThanOrEqualTo(this Span parameter, int length, SpanExceptionFactory exceptionFactory)
- {
- if (parameter.Length > length)
- {
- Throw.CustomSpanException(exceptionFactory, parameter, length);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws an .
- ///
- /// The span to be checked.
- /// The length value that the span must be shorter than or equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is longer than .
+ /// The type to be checked.
+ /// The type describing an interface or base class that should derive from or implement.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeShorterThanOrEqualTo(this ReadOnlySpan parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.Length > length)
- {
- Throw.SpanMustBeShorterThanOrEqualTo(parameter, length, parameterName, message);
- }
-
- return parameter;
- }
-
+ [ContractAnnotation("type:null => halt; baseClassOrInterfaceType:null => halt")]
+ public static bool InheritsFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type baseClassOrInterfaceType) => baseClassOrInterfaceType.MustNotBeNull(nameof(baseClassOrInterfaceType)).IsInterface ? type.Implements(baseClassOrInterfaceType) : type.DerivesFrom(baseClassOrInterfaceType);
///
- /// Ensures that the span is shorter than or equal to the specified length, or otherwise throws your custom exception.
+ /// Checks if the given type derives from the specified base class or interface type. This overload uses the specified
+ /// to compare the types.
///
- /// The span to be checked.
- /// The length value that the span must be shorter than or equal to.
- /// The delegate that creates your custom exception. and are passed to it.
- /// Your custom exception thrown when is longer than .
+ /// The type to be checked.
+ /// The type describing an interface or base class that should derive from or implement.
+ /// The equality comparer used to compare the types.
+ /// Thrown when , or , or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeShorterThanOrEqualTo(this ReadOnlySpan parameter, int length, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- if (parameter.Length > length)
- {
- Throw.CustomSpanException(exceptionFactory, parameter, length);
- }
-
- return parameter;
- }
-
+ [ContractAnnotation("type:null => halt; baseClassOrInterfaceType:null => halt; typeComparer:null => halt")]
+ public static bool InheritsFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type baseClassOrInterfaceType, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer) => baseClassOrInterfaceType.MustNotBeNull(nameof(baseClassOrInterfaceType)).IsInterface ? type.Implements(baseClassOrInterfaceType, typeComparer) : type.DerivesFrom(baseClassOrInterfaceType, typeComparer);
///
/// Checks if the specified is true and throws an in this case.
///
@@ -424,517 +255,313 @@ public static void InvalidArgument(bool condition, T parameter, Func
- /// Ensures that is not within the specified range, or otherwise throws an .
+ /// Checks if the specified is true and throws an in this case.
///
- /// The type of the parameter to be checked.
- /// The parameter to be checked.
- /// The range where must not be in-between.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is within .
- /// Thrown when is null.
+ /// The condition to be checked. The exception is thrown when it is true.
+ /// The message that will be passed to the (optional).
+ /// Thrown when is true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustNotBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where T : IComparable
+ public static void InvalidOperation(bool condition, string? message = null)
{
- if (range.IsValueWithinRange(parameter.MustNotBeNullReference(parameterName, message)))
+ if (condition)
{
- Throw.MustNotBeInRange(parameter, range, parameterName, message);
+ Throw.InvalidOperation(message);
}
-
- return parameter;
}
///
- /// Ensures that is not within the specified range, or otherwise throws your custom exception.
+ /// Checks if the specified is true and throws an in this case.
///
- /// The parameter to be checked.
- /// The range where must not be in-between.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when is within , or when is null.
+ /// The condition to be checked. The exception is thrown when it is true.
+ /// The message that will be passed to the .
+ /// Thrown when is true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustNotBeIn([NotNull][ValidatedNotNull] this T parameter, Range range, Func, Exception> exceptionFactory)
- where T : IComparable
+ public static void InvalidState(bool condition, string? message = null)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || range.IsValueWithinRange(parameter))
+ if (condition)
{
- Throw.CustomException(exceptionFactory, parameter!, range);
+ Throw.InvalidState(message);
}
-
- return parameter;
}
///
- /// Checks if the given is a generic type that has open generic parameters,
- /// but is no generic type definition.
+ /// Checks if the specified value is approximately the same as the other value, using the given tolerance.
///
- /// The type to be checked.
- /// Thrown when is null.
+ /// The first value to be compared.
+ /// The second value to be compared.
+ /// The tolerance indicating how much the two values may differ from each other.
+ ///
+ /// True if and are equal or if their absolute difference
+ /// is smaller than the given , otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("type:null => halt")]
- // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
- public static bool IsOpenConstructedGenericType([NotNull][ValidatedNotNull] this Type type) => type.MustNotBeNull(nameof(type)).IsGenericType && type.ContainsGenericParameters && type.IsGenericTypeDefinition == false;
+ public static bool IsApproximately(this double value, double other, double tolerance) => Math.Abs(value - other) <= tolerance;
///
- /// Checks if the specified character is a letter or digit.
+ /// Checks if the specified value is approximately the same as the other value, using the default tolerance of 0.0001.
///
+ /// The first value to be compared.
+ /// The second value to be compared.
+ ///
+ /// True if and are equal or if their absolute difference
+ /// is smaller than 0.0001, otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsLetterOrDigit(this char character) => char.IsLetterOrDigit(character);
+ public static bool IsApproximately(this double value, double other) => Math.Abs(value - other) <= 0.0001;
///
- /// Checks if the specified string is trimmed at the end, i.e. it does not end with
- /// white space characters. Inputting an empty string will return true.
+ /// Checks if the specified value is approximately the same as the other value, using the given tolerance.
///
- /// The string to be checked.
- ///
- /// The value indicating whether true or false should be returned from this method when the
- /// is null. The default value is true.
- ///
+ /// The first value to be compared.
+ /// The second value to be compared.
+ /// The tolerance indicating how much the two values may differ from each other.
///
- /// True if the is trimmed at the end, else false.
- /// An empty string will result in true.
+ /// True if and are equal or if their absolute difference
+ /// is smaller than the given , otherwise false.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsTrimmedAtEnd(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmedAtEnd();
+ public static bool IsApproximately(this float value, float other, float tolerance) => Math.Abs(value - other) <= tolerance;
///
- /// Checks if the specified character span is trimmed at the end, i.e. it does not end with
- /// white space characters. Inputting an empty span will return true.
+ /// Checks if the specified value is approximately the same as the other value, using the default tolerance of 0.0001f.
///
- /// The character span to be checked.
+ /// The first value to be compared.
+ /// The second value to be compared.
///
- /// True if the is trimmed at the end, else false.
- /// An empty span will result in true.
+ /// True if and are equal or if their absolute difference
+ /// is smaller than 0.0001f, otherwise false.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static bool IsTrimmedAtEnd(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[parameter.Length - 1].IsWhiteSpace();
- ///
- /// Ensures that the specified single-precision floating-point value is finite, or otherwise throws an .
- ///
+ public static bool IsApproximately(this float value, float other) => Math.Abs(value - other) <= 0.0001f;
+ /// Checks if the character is an ASCII code point.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeFinite(this float parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static bool IsAscii(this char parameter) => parameter <= 0x7F;
+ /// Checks if the byte is an ASCII value.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this byte parameter) => parameter <= 0x7F;
+ /// Checks if the string is non-null and contains only ASCII characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this string? parameter) => parameter is not null && parameter.AsSpan().IsAscii();
+ /// Checks if the character span contains only ASCII characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this Span parameter) => ((ReadOnlySpan)parameter).IsAscii();
+ /// Checks if the read-only character span contains only ASCII characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this ReadOnlySpan parameter)
{
- if (!parameter.IsFinite())
+ foreach (var value in parameter)
{
- Throw.NotFinite(parameter, parameterName, message);
+ if (value > 0x7F)
+ {
+ return false;
+ }
}
- return parameter;
+ return true;
}
- ///
- /// Ensures that the specified single-precision floating-point value is finite, or otherwise throws your custom exception.
- ///
+ /// Checks if the character memory contains only ASCII characters.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static float MustBeFinite(this float parameter, Func exceptionFactory)
+ public static bool IsAscii(this Memory parameter) => parameter.Span.IsAscii();
+ /// Checks if the read-only character memory contains only ASCII characters.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this ReadOnlyMemory parameter) => parameter.Span.IsAscii();
+ /// Checks if the byte span contains only ASCII values.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this Span parameter) => ((ReadOnlySpan)parameter).IsAscii();
+ /// Checks if the read-only byte span contains only ASCII values.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this ReadOnlySpan parameter)
{
- if (!parameter.IsFinite())
+ foreach (var value in parameter)
{
- Throw.CustomException(exceptionFactory, parameter);
+ if (value > 0x7F)
+ {
+ return false;
+ }
}
- return parameter;
+ return true;
}
+ /// Checks if the byte memory contains only ASCII values.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this Memory parameter) => parameter.Span.IsAscii();
+ /// Checks if the read-only byte memory contains only ASCII values.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsAscii(this ReadOnlyMemory parameter) => parameter.Span.IsAscii();
///
- /// Ensures that the specified double-precision floating-point value is finite, or otherwise throws an .
+ /// Checks if the specified character is a digit.
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeFinite(this double parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsFinite())
- {
- Throw.NotFinite(parameter, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsDigit(this char character) => char.IsDigit(character);
///
- /// Ensures that the specified double-precision floating-point value is finite, or otherwise throws your custom exception.
+ /// Checks if the specified string is an email address using the default email regular expression
+ /// defined in .
///
+ /// The string to be checked if it is an email address.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static double MustBeFinite(this double parameter, Func exceptionFactory)
- {
- if (!parameter.IsFinite())
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
+ [ContractAnnotation("emailAddress:null => false")]
+ public static bool IsEmailAddress([NotNullWhen(true)] this string? emailAddress) => emailAddress != null && RegularExpressions.EmailRegex.IsMatch(emailAddress);
///
- /// Ensures that the has at most the specified length, or otherwise throws an .
+ /// Checks if the specified string is an email address using the provided regular expression for validation.
///
- /// The to be checked.
- /// The maximum length the should have.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when has more than the specified length.
- /// The default instance of will be treated as having length 0.
+ /// The string to be checked.
+ /// The regular expression that determines whether the input string is an email address.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ImmutableArray MustHaveMaximumLength(this ImmutableArray parameter, int length, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
- if (parameterLength > length)
- {
- Throw.InvalidMaximumImmutableArrayLength(parameter, length, parameterName, message);
- }
-
- return parameter;
- }
-
+ [ContractAnnotation("emailAddress:null => false; emailAddressPattern:null => halt")]
+ public static bool IsEmailAddress([NotNullWhen(true)] this string? emailAddress, Regex emailAddressPattern) => emailAddress != null && emailAddressPattern.MustNotBeNull(nameof(emailAddressPattern)).IsMatch(emailAddress);
///
- /// Ensures that the has at most the specified length, or otherwise throws your custom exception.
+ /// Checks if the specified GUID is an empty one.
///
- /// The to be checked.
- /// The maximum length the should have.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when has more than the specified length.
- /// The default instance of will be treated as having length 0.
+ /// The GUID to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ImmutableArray MustHaveMaximumLength(this ImmutableArray parameter, int length, Func, int, Exception> exceptionFactory)
- {
- var parameterLength = parameter.IsDefault ? 0 : parameter.Length;
- if (parameterLength > length)
- {
- Throw.CustomException(exceptionFactory, parameter, length);
- }
-
- return parameter;
- }
-
+ public static bool IsEmpty(this Guid parameter) => parameter == Guid.Empty;
///
- /// Ensures that the specified URI is a relative one, or otherwise throws an .
+ /// Checks if the specified span is empty or contains only white space characters.
///
- /// The URI to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is an absolute URI.
- /// Thrown when is null.
+ /// The span to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeRelativeUri([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.MustNotBeNull(parameterName, message).IsAbsoluteUri)
- {
- Throw.MustBeRelativeUri(parameter, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsEmptyOrWhiteSpace(this Span span) => ((ReadOnlySpan)span).IsEmptyOrWhiteSpace();
///
- /// Ensures that the specified URI is a relative one, or otherwise throws your custom exception.
+ /// Checks if the specified span is empty or contains only white space characters.
///
- /// The URI to be checked.
- /// The delegate that creates your custom exception. is passed to this delegate.
- /// Your custom exception thrown when is an absolute URI, or when is null.
+ /// The span to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeRelativeUri([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory)
+ public static bool IsEmptyOrWhiteSpace(this ReadOnlySpan span)
{
- if (parameter is null || parameter.IsAbsoluteUri)
+ if (span.IsEmpty)
{
- Throw.CustomException(exceptionFactory, parameter);
+ return true;
}
- return parameter;
- }
-
- ///
- /// Ensures that the specified uses , or otherwise throws an .
- ///
- /// The date time to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not use .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static DateTime MustBeLocal(this DateTime parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.Kind != DateTimeKind.Local)
+ foreach (var character in span)
{
- Throw.MustBeLocalDateTime(parameter, parameterName, message);
+ if (!character.IsWhiteSpace())
+ {
+ return false;
+ }
}
- return parameter;
+ return true;
}
///
- /// Ensures that the specified uses , or otherwise throws your custom exception.
+ /// Checks if the specified memory is empty or contains only white space characters.
///
- /// The date time to be checked.
- /// The delegate that creates your custom exception. is passed to this delegate.
- /// Your custom exception thrown when does not use .
+ /// The memory to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static DateTime MustBeLocal(this DateTime parameter, Func exceptionFactory)
- {
- if (parameter.Kind != DateTimeKind.Local)
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
+ public static bool IsEmptyOrWhiteSpace(this Memory memory) => memory.Span.IsEmptyOrWhiteSpace();
///
- /// Ensures that the string matches the specified regular expression, or otherwise throws a .
+ /// Checks if the specified memory is empty or contains only white space characters.
///
- /// The string to be checked.
- /// The regular expression used for pattern matching.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when does not match the specified regular expression.
- /// Thrown when or is null.
+ /// The memory to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; regex:null => halt")]
- public static string MustMatch([NotNull][ValidatedNotNull] this string? parameter, Regex regex, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!regex.MustNotBeNull(nameof(regex), message).IsMatch(parameter.MustNotBeNull(parameterName, message)))
- {
- Throw.StringDoesNotMatch(parameter, regex, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsEmptyOrWhiteSpace(this ReadOnlyMemory memory) => memory.Span.IsEmptyOrWhiteSpace();
///
- /// Ensures that the string matches the specified regular expression, or otherwise throws your custom exception.
+ /// Checks if the two specified types are equivalent. This is true when both types are equal or
+ /// when one type is a constructed generic type and the other type is the corresponding generic type definition.
///
- /// The string to be checked.
- /// The regular expression used for pattern matching.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- ///
- /// Your custom exception thrown when does not match the specified regular expression,
- /// or when is null,
- /// or when is null.
- ///
+ /// The first type to be checked.
+ /// The other type to be checked.
+ ///
+ /// True if both types are null, or if both are equal, or if one type
+ /// is a constructed generic type and the other one is the corresponding generic type definition, else false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static string MustMatch([NotNull][ValidatedNotNull] this string? parameter, Regex regex, Func exceptionFactory)
+ public static bool IsEquivalentTypeTo(this Type? type, Type? other) => ReferenceEquals(type, other) || (type is not null && other is not null && (type == other || (type.IsConstructedGenericType != other.IsConstructedGenericType && CheckTypeEquivalency(type, other))));
+ private static bool CheckTypeEquivalency(Type type, Type other)
{
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || regex is null || !regex.IsMatch(parameter))
+ if (type.IsConstructedGenericType)
{
- Throw.CustomException(exceptionFactory, parameter, regex!);
+ return type.GetGenericTypeDefinition() == other;
}
- return parameter;
+ return other.GetGenericTypeDefinition() == type;
}
///
- /// Ensures that the specified is not default or empty, or otherwise throws an .
+ /// Checks if the specified string represents a valid file extension.
///
- /// The to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is default or empty.
+ ///
+ /// The string to be checked. It must start with a period (.) and can only contain letters, digits,
+ /// and additional periods.
+ ///
+ /// True if the string is a valid file extension, false otherwise.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ImmutableArray MustNotBeDefaultOrEmpty(this ImmutableArray parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.IsDefaultOrEmpty)
- {
- Throw.EmptyCollection(parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsFileExtension([NotNullWhen(true)] this string? value) => value != null && IsFileExtension(value.AsSpan());
///
- /// Ensures that the specified is not default or empty, or otherwise throws your custom exception.
+ /// Checks if the specified character span represents a valid file extension.
///
- /// The to be checked.
- /// The delegate that creates your custom exception. The is passed to this delegate.
- /// Your custom exception thrown when is default or empty.
+ ///
+ /// The character span to be checked. It must start with a period (.) and can only contain letters, digits,
+ /// and additional periods.
+ ///
+ /// True if the span is a valid file extension, false otherwise.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static ImmutableArray MustNotBeDefaultOrEmpty(this ImmutableArray parameter, Func, Exception> exceptionFactory)
- {
- if (parameter.IsDefaultOrEmpty)
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
+ public static bool IsFileExtension(this Span value) => IsFileExtension((ReadOnlySpan)value);
///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
+ /// Checks if the specified character memory represents a valid file extension.
///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
+ ///
+ /// The character span to be checked. It must start with a period (.) and can only contain letters, digits,
+ /// and additional periods.
+ ///
+ /// True if the span is a valid file extension, false otherwise.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeGreaterThanOrApproximately(this double parameter, double other, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null) => parameter.MustBeGreaterThanOrApproximately(other, 0.0001, parameterName, message);
+ public static bool IsFileExtension(this ReadOnlyMemory value) => IsFileExtension(value.Span);
///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
+ /// Checks if the specified character memory represents a valid file extension.
///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- ///
- /// The delegate that creates your custom exception. and
- /// are passed to this delegate.
+ ///
+ /// The character span to be checked. It must start with a period (.) and can only contain letters, digits,
+ /// and additional periods.
///
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
+ /// True if the span is a valid file extension, false otherwise.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeGreaterThanOrApproximately(this double parameter, double other, Func exceptionFactory)
- {
- if (!parameter.IsGreaterThanOrApproximately(other))
- {
- Throw.CustomException(exceptionFactory, parameter, other);
- }
-
- return parameter;
- }
-
+ public static bool IsFileExtension(this Memory value) => IsFileExtension(value.Span);
///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, or otherwise throws an .
+ /// Checks if the specified character span represents a valid file extension.
///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
+ ///
+ /// The character span to be checked. It must start with a period (.) and can only contain letters, digits,
+ /// and additional periods.
+ ///
+ /// True if the span is a valid file extension, false otherwise.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeGreaterThanOrApproximately(this double parameter, double other, double tolerance, [CallerArgumentExpression(nameof(parameter))] string? parameterName = null, string? message = null)
+ public static bool IsFileExtension(this ReadOnlySpan value)
{
- if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
- {
- Throw.MustBeGreaterThanOrApproximately(parameter, other, tolerance, parameterName, message);
- }
-
- return parameter;
- }
-
- ///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, or otherwise throws your custom exception.
- ///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
- ///
- /// The delegate that creates your custom exception. ,
- /// , and are passed to this delegate.
- ///
- ///
- /// Your custom exception thrown when is not greater than or approximately equal to .
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static double MustBeGreaterThanOrApproximately(this double parameter, double other, double tolerance, Func exceptionFactory)
- {
- if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
+ // ReSharper disable once UseIndexFromEndExpression -- cannot use index from end expression in .NET Standard 2.0
+ if (value.Length <= 1 || value[0] != '.' || value[value.Length - 1] == '.')
{
- Throw.CustomException(exceptionFactory, parameter, other, tolerance);
+ return false;
}
- return parameter;
- }
-
- ///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, using the default tolerance of 0.0001f, or otherwise throws an
- /// .
- ///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeGreaterThanOrApproximately(this float parameter, float other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustBeGreaterThanOrApproximately(other, 0.0001f, parameterName, message);
- ///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, using the default tolerance of 0.0001, or otherwise throws an
- /// .
- ///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- ///
- /// The delegate that creates your custom exception. and
- /// are passed to this delegate.
- ///
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeGreaterThanOrApproximately(this float parameter, float other, Func exceptionFactory)
- {
- if (!parameter.IsGreaterThanOrApproximately(other))
+ var hasAlphanumeric = false;
+ for (var i = 1; i < value.Length; i++)
{
- Throw.CustomException(exceptionFactory, parameter, other);
+ var character = value[i];
+ if (character.IsLetterOrDigit())
+ {
+ hasAlphanumeric = true;
+ }
+ else if (character != '.')
+ {
+ return false;
+ }
}
- return parameter;
+ return hasAlphanumeric;
}
///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, or otherwise throws an .
+ /// Checks if the specified single-precision floating-point value is finite.
///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when is not greater than or approximately equal to .
- ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeGreaterThanOrApproximately(this float parameter, float other, float tolerance, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
- {
- Throw.MustBeGreaterThanOrApproximately(parameter, other, tolerance, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsFinite(this float parameter) => parameter >= float.MinValue && parameter <= float.MaxValue;
///
- /// Ensures that the specified is greater than or approximately equal to the given
- /// value, or otherwise throws your custom exception.
+ /// Checks if the specified double-precision floating-point value is finite.
///
- /// The value to be checked.
- /// The value that should be greater than or approximately equal to.
- /// The tolerance indicating how much the two values may differ from each other.
- ///
- /// The delegate that creates your custom exception. ,
- /// , and are passed to this delegate.
- ///
- ///
- /// Your custom exception thrown when is not greater than or approximately equal to .
- ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static float MustBeGreaterThanOrApproximately(this float parameter, float other, float tolerance, Func exceptionFactory)
- {
- if (!parameter.IsGreaterThanOrApproximately(other, tolerance))
- {
- Throw.CustomException(exceptionFactory, parameter, other, tolerance);
- }
-
- return parameter;
- }
-
+ public static bool IsFinite(this double parameter) => parameter >= double.MinValue && parameter <= double.MaxValue;
///
/// Checks if the specified value is greater than or approximately the same as the other value, using the given tolerance.
///
@@ -982,378 +609,321 @@ public static float MustBeGreaterThanOrApproximately(this float parameter, float
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsGreaterThanOrApproximately(this float value, float other) => value > other || value.IsApproximately(other);
///
- /// Ensures that the specified is less than the given value, or otherwise throws an .
+ /// Checks if the value is within the specified range.
///
/// The comparable to be checked.
- /// The boundary value that must be greater than .
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when the specified is not less than .
+ /// The range where must be in-between.
+ /// True if the parameter is within the specified range, else false.
/// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustNotBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where T : IComparable
- {
- if (parameter.MustNotBeNullReference(parameterName, message).CompareTo(other) >= 0)
- {
- Throw.MustNotBeGreaterThanOrEqualTo(parameter, other, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsIn([NotNull][ValidatedNotNull] this T parameter, Range range)
+ where T : IComparable => range.IsValueWithinRange(parameter);
///
- /// Ensures that the specified is less than the given value, or otherwise throws your custom exception.
+ /// Checks if the specified value is less than or approximately the same as the other value, using the given tolerance.
///
- /// The comparable to be checked.
- /// The boundary value that must be greater than .
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when the specified is not less than , or when is null.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// The tolerance indicating how much the two values may differ from each other.
+ ///
+ /// True if is less than or if their absolute difference
+ /// is smaller than the given , otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustNotBeGreaterThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, Func exceptionFactory)
- where T : IComparable
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || parameter.CompareTo(other) >= 0)
- {
- Throw.CustomException(exceptionFactory, parameter!, other);
- }
-
- return parameter;
- }
-
+ public static bool IsLessThanOrApproximately(this double value, double other, double tolerance) => value < other || value.IsApproximately(other, tolerance);
///
- /// Ensures that the value is not one of the specified items, or otherwise throws a .
+ /// Checks if the specified value is less than or approximately the same as the other value, using the default tolerance of 0.0001.
///
- /// The value to be checked.
- /// The items that must not contain the value.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when is equal to one of the specified .
- /// Thrown when is null.
+ /// The first value to compare.
+ /// The second value to compare.
+ ///
+ /// True if is less than or if their absolute difference
+ /// is smaller than 0.0001, otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("items:null => halt")]
- // ReSharper disable once RedundantNullableFlowAttribute - the attribute has an effect, see Issue72NotNullAttribute tests
- public static TItem MustNotBeOneOf(this TItem parameter, [NotNull][ValidatedNotNull] IEnumerable items, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- // ReSharper disable PossibleMultipleEnumeration
- if (parameter.IsOneOf(items.MustNotBeNull(nameof(items), message)))
- {
- Throw.ValueIsOneOf(parameter, items, parameterName, message);
- }
-
- return parameter;
- // ReSharper restore PossibleMultipleEnumeration
- }
-
+ public static bool IsLessThanOrApproximately(this double value, double other) => value < other || value.IsApproximately(other);
///
- /// Ensures that the value is not one of the specified items, or otherwise throws your custom exception.
+ /// Checks if the specified value is less than or approximately the same as the other value, using the given tolerance.
///
- /// The value to be checked.
- /// The items that must not contain the value.
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when is equal to one of the specified , or when is null.
+ /// The first value to compare.
+ /// The second value to compare.
+ /// The tolerance indicating how much the two values may differ from each other.
+ ///
+ /// True if is less than or if their absolute difference
+ /// is smaller than the given , otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("items:null => halt")]
- public static TItem MustNotBeOneOf(this TItem parameter, [NotNull][ValidatedNotNull] TCollection items, Func exceptionFactory)
- where TCollection : class, IEnumerable
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (items is null || parameter.IsOneOf(items))
- {
- Throw.CustomException(exceptionFactory, parameter, items!);
- }
-
- return parameter;
- }
-
+ public static bool IsLessThanOrApproximately(this float value, float other, float tolerance) => value < other || value.IsApproximately(other, tolerance);
///
- /// Ensures that the specified URI has the "https" scheme, or otherwise throws an .
+ /// Checks if the specified value is less than or approximately the same as the other value, using the default tolerance of 0.0001f.
///
- /// The URI to be checked.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when uses a different scheme than "https".
- /// Thrown when is relative and thus has no scheme.
- /// Thrown when is null.
+ /// The first value to compare.
+ /// The second value to compare.
+ ///
+ /// True if is less than or if their absolute difference
+ /// is smaller than 0.0001f, otherwise false.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null) => parameter.MustHaveScheme("https", parameterName, message);
+ public static bool IsLessThanOrApproximately(this float value, float other) => value < other || value.IsApproximately(other);
///
- /// Ensures that the specified URI has the "https" scheme, or otherwise throws your custom exception.
+ /// Checks if the specified character is a letter.
///
- /// The URI to be checked.
- /// The delegate that creates the exception to be thrown. is passed to this delegate.
- /// Your custom exception thrown when uses a different scheme than "https", or when is a relative URI, or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static Uri MustBeHttpsUrl([NotNull][ValidatedNotNull] this Uri? parameter, Func exceptionFactory) => parameter.MustHaveScheme("https", exceptionFactory);
+ public static bool IsLetter(this char character) => char.IsLetter(character);
///
- /// Ensures that the specified is not greater than the given value, or otherwise throws an .
+ /// Checks if the specified character is a letter or digit.
///
- /// The comparable to be checked.
- /// The boundary value that must be greater than or equal to .
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when the specified is greater than .
- /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustBeLessThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- where T : IComparable
- {
- if (parameter.MustNotBeNullReference(parameterName, message).CompareTo(other) > 0)
- {
- Throw.MustBeLessThanOrEqualTo(parameter, other, parameterName, message);
- }
-
- return parameter;
- }
-
+ public static bool IsLetterOrDigit(this char character) => char.IsLetterOrDigit(character);
///
- /// Ensures that the specified is not greater than the given value, or otherwise throws your custom exception.
+ /// Checks if the string is either "\n" or "\r\n". This is done independently of the current value of .
+ ///
+ /// The string to be checked.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [ContractAnnotation("=> false, parameter:canbenull; => true, parameter:notnull")]
+ public static bool IsNewLine([NotNullWhen(true)] this string? parameter) => parameter == "\n" || parameter == "\r\n";
+ ///
+ /// Checks if the value is not within the specified range.
///
/// The comparable to be checked.
- /// The boundary value that must be greater than or equal to .
- /// The delegate that creates your custom exception. and are passed to this delegate.
- /// Your custom exception thrown when the specified is greater than , or when is null.
+ /// The range where must not be in-between.
+ /// True if the parameter is not within the specified range, else false.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustBeLessThanOrEqualTo([NotNull][ValidatedNotNull] this T parameter, T other, Func exceptionFactory)
- where T : IComparable
- {
- // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract - caller might have NRTs turned off
- if (parameter is null || parameter.CompareTo(other) > 0)
- {
- Throw.CustomException(exceptionFactory, parameter!, other);
- }
-
- return parameter;
- }
-
- /// Ensures that the character is ASCII, or otherwise throws an .
+ public static bool IsNotIn([NotNull][ValidatedNotNull] this T parameter, Range range)
+ where T : IComparable => !range.IsValueWithinRange(parameter);
+ ///
+ /// Checks if the specified collection is null or empty.
+ ///
+ /// The collection to be checked.
+ /// True if the collection is null or empty, else false.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static char MustBeAscii(this char parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsAscii())
- {
- Throw.Argument(parameterName, message ?? $"{parameterName ?? "The character"} must be ASCII, but it actually is '{parameter}'.");
- }
-
- return parameter;
- }
-
- /// Ensures that the character is ASCII, or otherwise throws your custom exception.
+ [ContractAnnotation("=> true, collection:canbenull; => false, collection:notnull")]
+ public static bool IsNullOrEmpty([NotNullWhen(false)] this IEnumerable? collection) => collection is null || collection.Count() == 0;
+ ///
+ /// Checks if the specified string is null or empty.
+ ///
+ /// The string to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static char MustBeAscii(this char parameter, Func exceptionFactory)
- {
- if (!parameter.IsAscii())
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
- /// Ensures that the byte is ASCII, or otherwise throws an .
+ [ContractAnnotation("=> false, string:notnull; => true, string:canbenull")]
+ public static bool IsNullOrEmpty([NotNullWhen(false)] this string? @string) => string.IsNullOrEmpty(@string);
+ ///
+ /// Checks if the specified string is null, empty, or contains only white space.
+ ///
+ /// The string to be checked.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static byte MustBeAscii(this byte parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsAscii())
- {
- Throw.Argument(parameterName, message ?? $"{parameterName ?? "The byte"} must be ASCII, but it actually is {parameter}.");
- }
-
- return parameter;
- }
-
- /// Ensures that the byte is ASCII, or otherwise throws your custom exception.
+ [ContractAnnotation("=> false, string:notnull; => true, string:canbenull")]
+ public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? @string) => string.IsNullOrWhiteSpace(@string);
+ ///
+ /// Checks if the given is one of the specified .
+ ///
+ /// The item to be checked.
+ /// The collection that might contain the .
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("exceptionFactory:null => halt")]
- public static byte MustBeAscii(this byte parameter, Func exceptionFactory)
+ [ContractAnnotation("items:null => halt")]
+ // ReSharper disable once RedundantNullableFlowAttribute - the attribute has an effect, see Issue72NotNullAttribute tests
+ public static bool IsOneOf(this TItem item, [NotNull][ValidatedNotNull] IEnumerable items)
{
- if (!parameter.IsAscii())
+ if (items is ICollection collection)
{
- Throw.CustomException(exceptionFactory, parameter);
+ return collection.Contains(item);
}
- return parameter;
- }
-
- /// Ensures that the string is non-null and contains only ASCII characters.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeAscii([NotNull][ValidatedNotNull] this string? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- parameter.MustNotBeNull(parameterName, message);
- if (!parameter.IsAscii())
+ if (items is string @string && item is char character)
{
- Throw.Argument(parameterName, message ?? $"{parameterName ?? "The string"} must contain only ASCII characters.");
+ return @string.IndexOf(character) != -1;
}
- return parameter;
+ return items.MustNotBeNull(nameof(items)).ContainsViaForeach(item);
}
- /// Ensures that the string is non-null and contains only ASCII characters, or otherwise throws your custom exception.
+ ///
+ /// Checks if the given is a generic type that has open generic parameters,
+ /// but is no generic type definition.
+ ///
+ /// The type to be checked.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static string MustBeAscii([NotNull][ValidatedNotNull] this string? parameter, Func exceptionFactory)
- {
- if (parameter is null || !parameter.IsAscii())
- {
- Throw.CustomException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
- /// Ensures that the character span contains only ASCII characters.
+ [ContractAnnotation("type:null => halt")]
+ // ReSharper disable once RedundantNullableFlowAttribute -- NotNull has an effect, see Issue72NotNullAttributeTests
+ public static bool IsOpenConstructedGenericType([NotNull][ValidatedNotNull] this Type type) => type.MustNotBeNull(nameof(type)).IsGenericType && type.ContainsGenericParameters && type.IsGenericTypeDefinition == false;
+ ///
+ /// Checks if the given is equal to the specified or if it derives from it. Internally, this
+ /// method uses so that constructed generic types and their corresponding generic type definitions are regarded as equal.
+ ///
+ /// The type to be checked.
+ /// The type that is equivalent to or the base class type where derives from.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeAscii(this Span parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- ((ReadOnlySpan)parameter).MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the character span contains only ASCII characters, or otherwise throws your custom exception.
+ [ContractAnnotation("type:null => halt; otherType:null => halt")]
+ public static bool IsOrDerivesFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType) => type.IsEquivalentTypeTo(otherType.MustNotBeNull(nameof(otherType))) || type.DerivesFrom(otherType);
+ ///
+ /// Checks if the given is equal to the specified or if it derives from it. This overload uses the specified
+ /// to compare the types.
+ ///
+ /// The type to be checked.
+ /// The type that is equivalent to or the base class type where derives from.
+ /// The equality comparer used to compare the types.
+ /// Thrown when , or , or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeAscii(this Span parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- ((ReadOnlySpan)parameter).MustBeAscii(exceptionFactory);
- return parameter;
- }
-
- /// Ensures that the read-only character span contains only ASCII characters.
+ [ContractAnnotation("type:null => halt; otherType:null => halt; typeComparer:null => halt")]
+ public static bool IsOrDerivesFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer) => typeComparer.MustNotBeNull(nameof(typeComparer)).Equals(type, otherType.MustNotBeNull(nameof(otherType))) || type.DerivesFrom(otherType, typeComparer);
+ ///
+ /// Checks if the given is equal to the specified or if it implements it. Internally, this
+ /// method uses so that constructed generic types and their corresponding generic type definitions are regarded as equal.
+ ///
+ /// The type to be checked.
+ /// The type that is equivalent to or the interface type that implements.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeAscii(this ReadOnlySpan parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsAscii())
- {
- Throw.Argument(parameterName, message ?? $"{parameterName ?? "The character span"} must contain only ASCII characters.");
- }
-
- return parameter;
- }
-
- /// Ensures that the read-only character span contains only ASCII characters, or otherwise throws your custom exception.
+ [ContractAnnotation("type:null => halt; otherType:null => halt")]
+ public static bool IsOrImplements([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType) => type.IsEquivalentTypeTo(otherType.MustNotBeNull(nameof(otherType))) || type.Implements(otherType);
+ ///
+ /// Checks if the given is equal to the specified or if it implements it. This overload uses the specified
+ /// to compare the types.
+ ///
+ /// ,
+ /// The type to be checked.
+ /// The type that is equivalent to or the interface type that implements.
+ /// The equality comparer used to compare the interface types.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeAscii(this ReadOnlySpan parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- if (!parameter.IsAscii())
- {
- Throw.CustomSpanException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
- /// Ensures that the character memory contains only ASCII characters.
+ [ContractAnnotation("type:null => halt; otherType:null => halt")]
+ public static bool IsOrImplements([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer) => typeComparer.MustNotBeNull(nameof(typeComparer)).Equals(type.MustNotBeNull(nameof(type)), otherType.MustNotBeNull(nameof(otherType))) || type.Implements(otherType, typeComparer);
+ ///
+ /// Checks if the given is equal to the specified or if it derives from it or implements it.
+ /// Internally, this method uses so that constructed generic types and their corresponding generic type definitions
+ /// are regarded as equal.
+ ///
+ /// The type to be checked.
+ /// The type that is equivalent to or the base class type where derives from.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Memory MustBeAscii(this Memory parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- ((ReadOnlySpan)parameter.Span).MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the character memory contains only ASCII characters, or otherwise throws your custom exception.
+ [ContractAnnotation("type:null => halt; otherType:null => halt")]
+ public static bool IsOrInheritsFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType) => type.IsEquivalentTypeTo(otherType.MustNotBeNull(nameof(otherType))) || type.InheritsFrom(otherType);
+ ///
+ /// Checks if the given is equal to the specified or if it derives from it or implements it.
+ /// This overload uses the specified to compare the types.
+ ///
+ /// The type to be checked.
+ /// The type that is equivalent to or the base class type where derives from.
+ /// The equality comparer used to compare the types.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Memory MustBeAscii(this Memory parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- ((ReadOnlySpan)parameter.Span).MustBeAscii(exceptionFactory);
- return parameter;
- }
-
- /// Ensures that the read-only character memory contains only ASCII characters.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlyMemory MustBeAscii(this ReadOnlyMemory parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- parameter.Span.MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the read-only character memory contains only ASCII characters, or otherwise throws your custom exception.
+ [ContractAnnotation("type:null => halt; otherType:null => halt; typeComparer:null => halt")]
+ public static bool IsOrInheritsFrom([NotNull][ValidatedNotNull] this Type type, [NotNull][ValidatedNotNull] Type otherType, [NotNull][ValidatedNotNull] IEqualityComparer typeComparer) => typeComparer.MustNotBeNull(nameof(typeComparer)).Equals(type, otherType.MustNotBeNull(nameof(otherType))) || type.InheritsFrom(otherType, typeComparer);
+ ///
+ /// Checks if and point to the same object.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlyMemory MustBeAscii(this ReadOnlyMemory parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- parameter.Span.MustBeAscii(exceptionFactory);
- return parameter;
- }
-
- /// Ensures that the byte span contains only ASCII values.
+ // ReSharper disable StringLiteralTypo
+ [ContractAnnotation("parameter:notNull => true, other:notnull; parameter:notNull => false, other:canbenull; other:notnull => true, parameter:notnull; other:notnull => false, parameter:canbenull")]
+ // ReSharper restore StringLiteralTypo
+ public static bool IsSameAs([NoEnumeration] this T? parameter, [NoEnumeration] T? other)
+ where T : class => ReferenceEquals(parameter, other);
+ ///
+ /// Checks if the string is a substring of the other string.
+ ///
+ /// The string to be checked.
+ /// The other string.
+ /// True if is a substring of , else false.
+ /// Thrown when or is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeAscii(this Span parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- ((ReadOnlySpan)parameter).MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the byte span contains only ASCII values, or otherwise throws your custom exception.
+ [ContractAnnotation("value:null => halt; other:null => halt")]
+ // ReSharper disable RedundantNullableFlowAttribute
+ public static bool IsSubstringOf([NotNull][ValidatedNotNull] this string value, [NotNull][ValidatedNotNull] string other) => other.MustNotBeNull(nameof(other)).Contains(value);
+ // ReSharper restore RedundantNullableFlowAttribute
+ ///
+ /// Checks if the string is a substring of the other string.
+ ///
+ /// The string to be checked.
+ /// The other string.
+ /// One of the enumeration values that specifies the rules for the search.
+ /// True if is a substring of , else false.
+ /// Thrown when or is null.
+ /// Thrown when is not a valid value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Span MustBeAscii(this Span parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- ((ReadOnlySpan)parameter).MustBeAscii(exceptionFactory);
- return parameter;
- }
-
- /// Ensures that the read-only byte span contains only ASCII values.
+ [ContractAnnotation("value:null => halt; other:null => halt")]
+ // ReSharper disable RedundantNullableFlowAttribute
+ public static bool IsSubstringOf([NotNull][ValidatedNotNull] this string value, [NotNull][ValidatedNotNull] string other, StringComparison comparisonType) => other.MustNotBeNull(nameof(other)).IndexOf(value, comparisonType) != -1;
+ ///
+ /// Checks if the specified string is trimmed, i.e. it does not start or end with
+ /// white space characters. Inputting an empty string will return true. When null is passed,
+ /// you can control the return value with which will
+ /// return true by default.
+ ///
+ /// The string to be checked.
+ ///
+ /// The value indicating whether true or false should be returned from this method when the
+ /// is null. The default value is true.
+ ///
+ ///
+ /// True if the is trimmed, else false. An empty string will result in true.
+ /// You can control the return value with when the
+ /// is null.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeAscii(this ReadOnlySpan parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (!parameter.IsAscii())
- {
- Throw.Argument(parameterName, message ?? $"{parameterName ?? "The byte span"} must contain only ASCII values.");
- }
-
- return parameter;
- }
-
- /// Ensures that the read-only byte span contains only ASCII values, or otherwise throws your custom exception.
+ public static bool IsTrimmed(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmed();
+ ///
+ /// Checks if the specified character span is trimmed, i.e. it does not start or end with
+ /// white space characters. Inputting an empty span will return true.
+ ///
+ /// The character span to be checked.
+ /// True if the is trimmed, else false. An empty span will result in true.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan MustBeAscii(this ReadOnlySpan parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- if (!parameter.IsAscii())
- {
- Throw.CustomSpanException(exceptionFactory, parameter);
- }
-
- return parameter;
- }
-
- /// Ensures that the byte memory contains only ASCII values.
+ public static bool IsTrimmed(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[0].IsWhiteSpace() && !parameter[parameter.Length - 1].IsWhiteSpace();
+ ///
+ /// Checks if the specified string is trimmed at the end, i.e. it does not end with
+ /// white space characters. Inputting an empty string will return true.
+ ///
+ /// The string to be checked.
+ ///
+ /// The value indicating whether true or false should be returned from this method when the
+ /// is null. The default value is true.
+ ///
+ ///
+ /// True if the is trimmed at the end, else false.
+ /// An empty string will result in true.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Memory MustBeAscii(this Memory parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- ((ReadOnlySpan)parameter.Span).MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the byte memory contains only ASCII values, or otherwise throws your custom exception.
+ public static bool IsTrimmedAtEnd(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmedAtEnd();
+ ///
+ /// Checks if the specified character span is trimmed at the end, i.e. it does not end with
+ /// white space characters. Inputting an empty span will return true.
+ ///
+ /// The character span to be checked.
+ ///
+ /// True if the is trimmed at the end, else false.
+ /// An empty span will result in true.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Memory MustBeAscii(this Memory parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- ((ReadOnlySpan)parameter.Span).MustBeAscii(exceptionFactory);
- return parameter;
- }
-
- /// Ensures that the read-only byte memory contains only ASCII values.
+ public static bool IsTrimmedAtEnd(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[parameter.Length - 1].IsWhiteSpace();
+ ///
+ /// Checks if the specified string is trimmed at the start, i.e. it does not start with
+ /// white space characters. Inputting an empty string will return true.
+ ///
+ /// The string to be checked.
+ ///
+ /// The value indicating whether true or false should be returned from this method when the
+ /// is null. The default value is true.
+ ///
+ ///
+ /// True if the is trimmed at the start, else false.
+ /// An empty string will result in true.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlyMemory MustBeAscii(this ReadOnlyMemory parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- parameter.Span.MustBeAscii(parameterName, message);
- return parameter;
- }
-
- /// Ensures that the read-only byte memory contains only ASCII values, or otherwise throws your custom exception.
+ public static bool IsTrimmedAtStart(this string? parameter, bool regardNullAsTrimmed = true) => parameter is null ? regardNullAsTrimmed : parameter.AsSpan().IsTrimmedAtStart();
+ ///
+ /// Checks if the specified character span is trimmed at the start, i.e. it does not start with
+ /// white space characters. Inputting an empty span will return true.
+ ///
+ /// The character span to be checked.
+ ///
+ /// True if the is trimmed at the start, else false.
+ /// An empty span will result in true.
+ ///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlyMemory MustBeAscii(this ReadOnlyMemory parameter, ReadOnlySpanExceptionFactory exceptionFactory)
- {
- parameter.Span.MustBeAscii(exceptionFactory);
- return parameter;
- }
-
+ public static bool IsTrimmedAtStart(this ReadOnlySpan parameter) => parameter.Length == 0 || !parameter[0].IsWhiteSpace();
///
/// Checks if the specified GUID structurally identifies an RFC/IETF UUID version 7.
///
@@ -1367,1120 +937,911 @@ public static bool IsUuidVersion7(this Guid parameter)
}
///
- /// Ensures that the string is not null and trimmed at the end, or otherwise throws a .
- /// Empty strings are regarded as trimmed.
+ /// Checks if the specified value is a valid enum value of its type. This is true when the specified value
+ /// is one of the constants defined in the enum, or a valid flags combination when the enum type is marked
+ /// with the .
///
- /// The string to be checked.
+ /// The type of the enum.
+ /// The enum value to be checked.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsValidEnumValue(this T parameter)
+ where T : struct, Enum => EnumInfo.IsValidEnumValue(parameter);
+ ///
+ /// Checks if the specified character is a white space character.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static bool IsWhiteSpace(this char character) => char.IsWhiteSpace(character);
+ ///
+ /// Ensures that is equal to using the default equality comparer, or otherwise throws a .
+ ///
+ /// The first value to be compared.
+ /// The other value to be compared.
/// The name of the parameter (optional).
/// The message that will be passed to the resulting exception (optional).
- ///
- /// Thrown when is not trimmed at the end, i.e. they end with white space characters.
- /// Empty strings are regarded as trimmed.
- ///
- /// Thrown when is null.
+ /// Thrown when and are not equal.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeTrimmedAtEnd([NotNull][ValidatedNotNull] this string? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
+ public static T MustBe(this T parameter, T other, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (!parameter.MustNotBeNull(parameterName, message).IsTrimmedAtEnd())
+ if (!EqualityComparer.Default.Equals(parameter, other))
{
- Throw.NotTrimmedAtEnd(parameter, parameterName, message);
+ Throw.ValuesNotEqual(parameter, other, parameterName, message);
}
return parameter;
}
///
- /// Ensures that the string is not null and trimmed at the end, or otherwise throws your custom exception.
- /// Empty strings are regarded as trimmed.
+ /// Ensures that is equal to using the default equality comparer, or otherwise throws your custom exception.
///
- /// The string to be checked.
- /// The delegate that creates your custom exception. is passed to this delegate.
- /// Your custom exception thrown when is null or not trimmed at the end. Empty strings are regarded as trimmed.
+ /// The first value to be compared.
+ /// The other value to be compared.
+ /// The delegate that creates your custom exception. and are passed to this delegate.
+ /// Your custom exception thrown when and are not equal.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static string MustBeTrimmedAtEnd([NotNull][ValidatedNotNull] this string? parameter, Func exceptionFactory)
+ public static T MustBe(this T parameter, T other, Func exceptionFactory)
{
- if (parameter is null || !parameter.AsSpan().IsTrimmedAtEnd())
+ if (!EqualityComparer.Default.Equals(parameter, other))
{
- Throw.CustomException(exceptionFactory, parameter);
+ Throw.CustomException(exceptionFactory, parameter, other);
}
return parameter;
}
///
- /// Checks if the specified is true and throws an in this case.
+ /// Ensures that is equal to using the specified equality comparer, or otherwise throws a .
///
- /// The condition to be checked. The exception is thrown when it is true.
- /// The message that will be passed to the .
- /// Thrown when is true.
+ /// The first value to be compared.
+ /// The other value to be compared.
+ /// The equality comparer used for comparing the two values.
+ /// The name of the parameter (optional).
+ /// The message that will be passed to the resulting exception (optional).
+ /// Thrown when and are not equal.
+ /// Thrown when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void InvalidState(bool condition, string? message = null)
+ [ContractAnnotation("equalityComparer:null => halt")]
+ public static T MustBe(this T parameter, T other, IEqualityComparer equalityComparer, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
{
- if (condition)
+ if (!equalityComparer.MustNotBeNull(nameof(equalityComparer), message).Equals(parameter, other))
{
- Throw.InvalidState(message);
+ Throw.ValuesNotEqual(parameter, other, parameterName, message);
}
- }
- ///
- /// Ensures that can be cast to and returns the cast value, or otherwise throws a .
- ///
- /// The value to be cast.
- /// The name of the parameter (optional).
- /// The message that will be passed to the resulting exception (optional).
- /// Thrown when cannot be cast to .
- /// Thrown when is null.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull")]
- public static T MustBeOfType([NotNull, ValidatedNotNull, NoEnumeration] this object? parameter, [CallerArgumentExpression("parameter")] string? parameterName = null, string? message = null)
- {
- if (parameter.MustNotBeNull(parameterName, message)is T castValue)
- return castValue;
- Throw.InvalidTypeCast(parameter, typeof(T), parameterName, message);
- return default;
+ return parameter;
}
///
- /// Ensures that can be cast to and returns the cast value, or otherwise throws your custom exception.
+ /// Ensures that is equal to using the specified equality comparer, or otherwise throws your custom exception.
///
- /// The value to be cast.
- /// The delegate that creates your custom exception. The is passed to this delegate.
- /// Your custom exception thrown when cannot be cast to .
+ /// The first value to be compared.
+ /// The other value to be compared.
+ /// The equality comparer used for comparing the two values.
+ /// The delegate that creates your custom exception. , , and are passed to this delegate.
+ /// Your custom exception thrown when and are not equal, or when is null.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- [ContractAnnotation("parameter:null => halt; parameter:notnull => notnull; exceptionFactory:null => halt")]
- public static T MustBeOfType([NotNull, ValidatedNotNull, NoEnumeration] this object? parameter, Func