Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnetcore.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: .NET Core Tests and CodeQL Security Analysis

on:
[ push, pull_request ]
[ pull_request ]

jobs:
build:
Expand Down
2 changes: 1 addition & 1 deletion src/Validations/Algorithms/Checksum/LuhnFormula.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public static bool IsValid([NotNull] string? fullDigits)
[return: NotNull]
private static string ValidateDigitsAsString([NotNull] string? fullDigits)
{
string notNullDigits = fullDigits.ValueOrThrowIfNullOrZeroLength(nameof(fullDigits));
string notNullDigits = fullDigits.CheckNotZeroLength(nameof(fullDigits));

return notNullDigits.Length switch
{
Expand Down
39 changes: 19 additions & 20 deletions src/Validations/Arguments.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static partial class Arguments
public static TParamType OrException<TParamType>(
[NotNull] TParamType? value,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "") where TParamType : class
=> NullAndEmptyChecks.NotNull(value, paramName);
=> NullAndEmptyChecks.Check(value, paramName);

/// <summary>
/// Checks that the provided value is not <see langword="null" />.
Expand All @@ -52,7 +52,7 @@ public static TParamType OrExceptionWithMessage<TParamType>(
[NotNull] string customMessage,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
where TParamType : class
=> NullAndEmptyChecks.NotNull(value, paramName, customMessage);
=> NullAndEmptyChecks.Check(value, paramName, customMessage);

/// <summary>
/// Checks that the provided value is not <see langword="null" />, empty (zero length), or contains white-space
Expand Down Expand Up @@ -123,7 +123,7 @@ public static string NotEmptyOrException(
public static Guid NotEmptyOrException(Guid value,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
{
string validParamName = paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly();
string validParamName = paramName.CheckParamName();

return IsEmpty(value) ? throw new ArgumentException(validParamName) : value;
}
Expand Down Expand Up @@ -168,15 +168,15 @@ public static Guid NotEmptyOrExceptionWithMessage(Guid value,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
{
(string validParamName, string validCustomMessage) =
(paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(),
customMessage.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly());
(paramName.CheckParamName(),
customMessage.CheckExceptionMessage());

return IsEmpty(value) ?
throw new ArgumentException(paramName: validParamName, message: validCustomMessage)
: value;
}

private static bool IsEmpty(Guid value) => value == default;
private static bool IsEmpty(Guid value) => value == Guid.Empty;

#endregion

Expand Down Expand Up @@ -480,10 +480,10 @@ public static string ValidLuhnChecksum([NotNull] string? value, [NotNull] string
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
{
(string validParamName, string validCustomMessage) =
(paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(),
customMessage.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly());
(paramName.CheckParamName(),
customMessage.CheckExceptionMessage());

string notNullValue = NullAndEmptyChecks.NotNull(value, validParamName);
string notNullValue = NullAndEmptyChecks.Check(value, validParamName);

ValidateLuhnSequenceFormat(notNullValue, validCustomMessage);

Expand Down Expand Up @@ -521,10 +521,9 @@ private static int[] ToDigitsArray(string notNullValue)
[DebuggerStepThrough]
public static string ValidBase64([NotNull] string? value, [NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
{
string validParamName =
paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly();
string validParamName = paramName.CheckParamName();

string notNullValue = value.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(validParamName);
string notNullValue = value.CheckNotZeroLengthOrWhiteSpaceOnly(validParamName);

return IsBase64String(notNullValue) ? notNullValue
: throw new FormatException($"{validParamName} is not a valid Base64 String.");
Expand All @@ -544,8 +543,8 @@ public static string ValidBase64([NotNull] string? value, [NotNull] string custo
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
{
(string validParamName, string validCustomMessage) =
(paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(),
customMessage.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly());
(paramName.CheckParamName(),
customMessage.CheckExceptionMessage());

string notNullValue
= value.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(validParamName, validCustomMessage);
Expand Down Expand Up @@ -579,7 +578,7 @@ public static TNullable CompliesWith<TNullable>(
[NotNull] string preconditionDescription,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
where TNullable : class
=> CompliesWithExpected(value, validator, paramName, preconditionDescription, true);
=> CompliesWithExpected(value, validator, preconditionDescription, paramName, true);

/// <summary>
/// Checks the given value for <see langword="null"/> and then if the its complies with the validator function.
Expand All @@ -597,7 +596,7 @@ public static TNullable DoesNotComplyWith<TNullable>(
[NotNull] string preconditionDescription,
[NotNull, CallerArgumentExpression(nameof(value))] string paramName = "")
where TNullable : class
=> CompliesWithExpected(value, validator, paramName, preconditionDescription, false);
=> CompliesWithExpected(value, validator, preconditionDescription, paramName, false);

[return: NotNull]
private static TNullable CompliesWithExpected<TNullable>(
Expand All @@ -607,11 +606,11 @@ private static TNullable CompliesWithExpected<TNullable>(
[NotNull] string paramName,
bool expected) where TNullable : class
{
TNullable notNullValue = value.ValueOrThrowIfNull(nameof(value));
Func<TNullable, bool> notNullValidator = validator.ValueOrThrowIfNull();
string notNullParamName = paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly();
TNullable notNullValue = value.Check();
Func<TNullable, bool> notNullValidator = validator.Check();
string notNullParamName = paramName.CheckParamName();
string notNullPreconditionDescription
= preconditionDescription.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly();
= preconditionDescription.CheckExceptionMessage();

return notNullValidator(notNullValue) != expected
? throw new ArgumentException(paramName: notNullParamName, message: notNullPreconditionDescription)
Expand Down
79 changes: 48 additions & 31 deletions src/Validations/ArgumentsHelpers/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,66 +6,63 @@ namespace Triplex.Validations.ArgumentsHelpers;
internal static class Extensions
{
[return: NotNull]
internal static T ValueOrThrowIfNull<T>([NotNull] this T? value,
internal static T Check<T>([NotNull] this T? value,
[CallerArgumentExpression(nameof(value))] string paramName = "")
=> value ?? throw new ArgumentNullException(paramName);

[return: NotNull]
internal static T ValueOrThrowIfNull<T>([NotNull] this T? value, string paramName, string customMessage)
internal static T CheckWithParamName<T>([NotNull] this T? value, string paramName)
=> value ?? throw new ArgumentNullException(paramName);

[return: NotNull]
internal static T CheckWithParamName<T>([NotNull] this T? value, string paramName, string customMessage)
=> value ?? throw new ArgumentNullException(paramName, customMessage);

[return: NotNull]
internal static T ValueOrThrowInvalidOperationIfNull<T>([NotNull] this T? stateElement,
internal static T CheckOrInvalidOperationException<T>([NotNull] this T? stateElement,
string elementName)
=> stateElement
?? throw new InvalidOperationException($"Operation not allowed when {elementName} is null.");

[return: NotNull]
internal static string ValueOrThrowIfZeroLength(this string value, string paramName)
=> ValueOrThrowIfZeroLength(value, paramName, "Can not be empty (zero length).");
internal static string CheckNotZeroLength([NotNull] this string? value, string paramName)
=> CheckWithParamName(value, paramName)
.DoCheckNotZeroLength(paramName, "Can not be empty (zero length).");

[return: NotNull]
internal static string ValueOrThrowIfZeroLength(this string value, string paramName, string customMessage)
internal static string CheckNotZeroLength([NotNull] this string? value, string paramName, string customMessage)
=> CheckWithParamName(value, paramName, customMessage)
.DoCheckNotZeroLength(paramName, customMessage);

[return: NotNull]
private static string DoCheckNotZeroLength(this string value, string paramName, string customMessage)
=> value.Length is not 0
? value
: throw new ArgumentFormatException(paramName: paramName, message: customMessage);

[return: NotNull]
internal static string ValueOrThrowIfWhiteSpaceOnly(this string value, string paramName)
=> ValueOrThrowIfWhiteSpaceOnly(value, paramName, "Can not be white-space only.");
internal static string CheckNotWhiteSpaceOnly(this string value, string paramName)
=> CheckNotWhiteSpaceOnly(value, paramName, "Can not be white-space only.");

[return: NotNull]
internal static string ValueOrThrowIfWhiteSpaceOnly(this string value, string paramName, string customMessage)
internal static string CheckNotWhiteSpaceOnly(this string value, string paramName, string customMessage)
=> value.Any(ch => ch.IsNotWhiteSpace())
? value
: throw new ArgumentFormatException(paramName: paramName, message: customMessage);

[return: NotNull]
internal static string ValueOrThrowIfNullOrZeroLength([NotNull] this string? value,
string paramName)
=> ValueOrThrowIfNull(value, paramName)
.ValueOrThrowIfZeroLength(paramName);

[return: NotNull]
internal static string ValueOrThrowIfNullOrZeroLength([NotNull] this string? value,
string paramName, string customMessage)
=> ValueOrThrowIfNull(value, paramName, customMessage)
.ValueOrThrowIfZeroLength(paramName, customMessage);

[return: NotNull]
internal static string ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(
[NotNull] this string? value,
[CallerArgumentExpression(nameof(value))] string paramName = "")
=> ValueOrThrowIfNull(value, paramName)
.ValueOrThrowIfZeroLength(paramName)
.ValueOrThrowIfWhiteSpaceOnly(paramName);
internal static string CheckNotZeroLengthOrWhiteSpaceOnly(
[NotNull] this string? value, string paramName = "")
=> CheckWithParamName(value, paramName)
.CheckNotZeroLength(paramName)
.CheckNotWhiteSpaceOnly(paramName);

[return: NotNull]
internal static string ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly([NotNull] this string? value,
string paramName, string customMessage)
=> ValueOrThrowIfNull(value, paramName, customMessage)
.ValueOrThrowIfZeroLength(paramName, customMessage)
.ValueOrThrowIfWhiteSpaceOnly(paramName, customMessage);
=> CheckWithParamName(value, paramName, customMessage)
.DoCheckNotZeroLength(paramName, customMessage)
.CheckNotWhiteSpaceOnly(paramName, customMessage);

internal static bool IsNotWhiteSpace(this char ch) => !char.IsWhiteSpace(ch);

Expand Down Expand Up @@ -97,9 +94,29 @@ internal static TEnumType ValueOrThrowIfNotDefined<TEnumType>(this TEnumType val
internal static TType[] ValueOrThrowIfNullOrWithLessThanElements<TType>(
[NotNull] this TType[]? value, int minimumElements, string paramName)
{
_ = OutOfRangeChecks.GreaterThanOrEqualTo(ValueOrThrowIfNull(value, paramName).Length, minimumElements, paramName);
_ = OutOfRangeChecks.GreaterThanOrEqualTo(CheckWithParamName(value, paramName).Length, minimumElements, paramName);

return value!;
}

#region ParameterName and Exception Messages Helpers

[return: NotNull]
internal static string CheckParamName(
[NotNull] this string? value,
[CallerArgumentExpression(nameof(value))] string paramName = "")
=> CheckWithParamName(value, paramName)
.CheckNotZeroLength(paramName)
.CheckNotWhiteSpaceOnly(paramName);

[return: NotNull]
internal static string CheckExceptionMessage(
[NotNull] this string? value,
[CallerArgumentExpression(nameof(value))] string paramName = "")
=> CheckWithParamName(value, paramName)
.CheckNotZeroLength(paramName)
.CheckNotWhiteSpaceOnly(paramName);

#endregion
}
#pragma warning restore CA1303 // Do not pass literals as localized parameters
42 changes: 23 additions & 19 deletions src/Validations/ArgumentsHelpers/NullAndEmptyChecks.cs
Original file line number Diff line number Diff line change
@@ -1,41 +1,45 @@
namespace Triplex.Validations.ArgumentsHelpers;

/// <summary>
/// Provides methods to validate that parameters are not null, empty, or whitespace.
/// These methods throw exceptions if the checks fail, ensuring that the parameters meet the expected criteria.
/// This class is intended for internal use within the Triplex library and should not be used directly by consumers.
/// </summary>
/// <remarks>
/// As a general design principle, all checks begin with a <see langword="null"/> check.
/// </remarks>
internal static class NullAndEmptyChecks
{
[return: NotNull]
internal static TParamType NotNull<TParamType>([NotNull] TParamType? value,
[NotNull] string paramName) where TParamType : class
=> value.ValueOrThrowIfNull(paramName.ValueOrThrowIfNull(nameof(paramName)));
internal static TParamType Check<TParamType>([NotNull] TParamType? value, [NotNull] string paramName)
where TParamType : class
=> value.CheckWithParamName(paramName.CheckParamName());

[return: NotNull]
internal static TParamType NotNull<TParamType>([NotNull] TParamType? value,
[NotNull] string paramName, [NotNull] string customMessage)
internal static TParamType Check<TParamType>([NotNull] TParamType? value, [NotNull] string paramName, [NotNull] string customMessage)
where TParamType : class
=> value.ValueOrThrowIfNull(paramName.ValueOrThrowIfNull(nameof(paramName)),
customMessage.ValueOrThrowIfNull(nameof(customMessage)));
=> value.CheckWithParamName(paramName.CheckParamName(), customMessage.CheckExceptionMessage());

[return: NotNull]
internal static string NotNullEmptyOrWhiteSpaceOnly([NotNull] string? value,
[NotNull] string paramName)
=> NotNullOrEmpty(value, paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly())
.ValueOrThrowIfWhiteSpaceOnly(paramName);
internal static string NotNullEmptyOrWhiteSpaceOnly([NotNull] string? value, [NotNull] string paramName)
=> NotNullOrEmpty(value, paramName.CheckParamName())
.CheckNotWhiteSpaceOnly(paramName);

[return: NotNull]
internal static string NotNullEmptyOrWhiteSpaceOnly([NotNull] string? value,
[NotNull] string paramName, [NotNull] string customMessage)
=> NotNullOrEmpty(value, paramName, customMessage)
.ValueOrThrowIfWhiteSpaceOnly(paramName, customMessage);
.CheckNotWhiteSpaceOnly(paramName, customMessage);

[return: NotNull]
internal static string NotNullOrEmpty([NotNull] string? value,
[NotNull] string paramName)
=> value.ValueOrThrowIfNullOrZeroLength(
paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly());
internal static string NotNullOrEmpty([NotNull] string? value, [NotNull] string paramName)
=> value.CheckNotZeroLength(
paramName.CheckParamName());

[return: NotNull]
internal static string NotNullOrEmpty([NotNull] string? value,
[NotNull] string paramName, [NotNull] string customMessage)
=> value.ValueOrThrowIfNullOrZeroLength(
paramName.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly(),
customMessage.ValueOrThrowIfNullZeroLengthOrWhiteSpaceOnly());
=> value.CheckNotZeroLength(
paramName.CheckParamName(),
customMessage.CheckExceptionMessage());
}
Loading
Loading