diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 243033f..9975a7d 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -11,6 +11,7 @@ on: env: USE_FULL_NUMERIC_PROVIDER: "true" + MSBUILDDISABLENODEREUSE: "1" jobs: build: @@ -18,14 +19,18 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Setup .NET - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@v5 with: global-json-file: global.json - name: Restore dependencies run: dotnet restore - name: Build run: dotnet build --no-restore - - name: Test - run: dotnet test --no-build --verbosity normal + - name: Test (.NET 8.0) + run: dotnet test --no-build --framework net8.0 --verbosity quiet + - name: Test (.NET 9.0) + run: dotnet test --no-build --framework net9.0 --verbosity quiet + - name: Test (.NET 10.0) + run: dotnet test --no-build --framework net10.0 --verbosity quiet diff --git a/Directory.Build.props b/Directory.Build.props index 93e6cb0..8f1b065 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -2,11 +2,11 @@ - 12.2.0 - 12.2.0 - 12.2.0 - net8.0;net9.0 - 13 + 13.0.0 + 13.0.0 + 13.0.0 + net8.0;net9.0;net10.0 + 14 enable true ONIXLabs @@ -41,16 +41,15 @@ + Exe true false false + true - - - - + @@ -62,9 +61,14 @@ - - + + + + + + + diff --git a/OnixLabs.Core.UnitTests/Linq/IEnumerableExtensionTests.cs b/OnixLabs.Core.UnitTests/Linq/IEnumerableExtensionTests.cs index 0e7dd97..439fc24 100644 --- a/OnixLabs.Core.UnitTests/Linq/IEnumerableExtensionTests.cs +++ b/OnixLabs.Core.UnitTests/Linq/IEnumerableExtensionTests.cs @@ -20,6 +20,7 @@ using System.Numerics; using OnixLabs.Core.Linq; using OnixLabs.Core.UnitTests.Data; +using static OnixLabs.Core.Collections.Collection; namespace OnixLabs.Core.UnitTests.Linq; @@ -30,7 +31,7 @@ public sealed class IEnumerableExtensionTests public void AllEqualByShouldProduceExpectedResultTrueWhenEnumerableIsEmpty() { // Given - IEnumerable> elements = []; + IEnumerable> elements = EmptyEnumerable>(); // When bool result = elements.AllEqualBy(element => element.Text); @@ -46,7 +47,7 @@ public void AllEqualByShouldProduceExpectedResultTrue() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("abc", 123, Guid.NewGuid()); Record element3 = new("abc", 123, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.AllEqualBy(element => element.Text); @@ -62,7 +63,7 @@ public void AllEqualByShouldProduceExpectedResultFalse() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("abc", 123, Guid.NewGuid()); Record element3 = new("xyz", 123, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.AllEqualBy(element => element.Text); @@ -78,7 +79,7 @@ public void AnyEqualByShouldProduceExpectedResultTrue() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("abc", 123, Guid.NewGuid()); Record element3 = new("xyz", 123, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.AnyEqualBy(element => element.Text); @@ -94,7 +95,7 @@ public void AnyEqualByShouldProduceExpectedResultFalse() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 123, Guid.NewGuid()); Record element3 = new("xyz", 123, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.AnyEqualBy(element => element.Text); @@ -108,7 +109,7 @@ public void CountShouldReturnCountOfAllElementsNonGeneric() { // Given const int expected = 3; - IEnumerable elements = new[] { 1, 2, 3 }; + IEnumerable elements = EnumerableOf(1, 2, 3); // When int actual = elements.Count(); @@ -125,7 +126,7 @@ public void CountNotShouldProduceExpectedResult() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 123, Guid.NewGuid()); Record element3 = new("xyz", 456, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When int actual = elements.CountNot(element => element.Number == 456); @@ -138,7 +139,7 @@ public void CountNotShouldProduceExpectedResult() public void FirstOrNoneShouldReturnNoneWhenEnumerableIsEmpty() { // Given - IEnumerable elements = []; + IEnumerable elements = EmptyEnumerable(); Optional expected = Optional.None; // When @@ -152,7 +153,7 @@ public void FirstOrNoneShouldReturnNoneWhenEnumerableIsEmpty() public void FirstOrNoneShouldReturnFirstElementWhenCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = 1; // When @@ -166,7 +167,7 @@ public void FirstOrNoneShouldReturnFirstElementWhenCollectionIsNotEmpty() public void FirstOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = 2; // When @@ -180,7 +181,7 @@ public void FirstOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIs public void FirstOrNoneShouldReturnNoneWhenNoElementMatchesPredicateAndCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = Optional.None; // When @@ -194,7 +195,7 @@ public void FirstOrNoneShouldReturnNoneWhenNoElementMatchesPredicateAndCollectio public void ForEachShouldProduceExpectedResultNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element(), new Element(), new Element() }; + IEnumerable enumerable = ArrayOf(new Element(), new Element(), new Element()); // When enumerable.ForEach(element => (element as Element)!.Called = true); @@ -207,7 +208,7 @@ public void ForEachShouldProduceExpectedResultNonGeneric() public void ForEachShouldProduceExpectedResult() { // Given - IEnumerable enumerable = new[] { new Element(), new Element(), new Element() }; + IEnumerable enumerable = ArrayOf(new Element(), new Element(), new Element()); // When enumerable.ForEach(element => element.Called = true); @@ -220,8 +221,8 @@ public void ForEachShouldProduceExpectedResult() public void GetContentHashCodeShouldProduceExpectedResultEqualNonGeneric() { // Given - IEnumerable enumerable1 = new[] { new Element(1), new Element(2), new Element(3) }; - IEnumerable enumerable2 = new[] { new Element(1), new Element(2), new Element(3) }; + IEnumerable enumerable1 = EnumerableOf(new Element(1), new Element(2), new Element(3)); + IEnumerable enumerable2 = EnumerableOf(new Element(1), new Element(2), new Element(3)); // When int hashCode1 = enumerable1.GetContentHashCode(); @@ -235,8 +236,8 @@ public void GetContentHashCodeShouldProduceExpectedResultEqualNonGeneric() public void GetContentHashCodeShouldProduceExpectedResultEqual() { // Given - IEnumerable enumerable1 = [new Element(1), new Element(2), new Element(3)]; - IEnumerable enumerable2 = [new Element(1), new Element(2), new Element(3)]; + IEnumerable enumerable1 = EnumerableOf(new Element(1), new Element(2), new Element(3)); + IEnumerable enumerable2 = EnumerableOf(new Element(1), new Element(2), new Element(3)); // When int hashCode1 = enumerable1.GetContentHashCode(); @@ -250,8 +251,8 @@ public void GetContentHashCodeShouldProduceExpectedResultEqual() public void GetContentHashCodeShouldProduceExpectedResultDifferent() { // Given - IEnumerable enumerable1 = [new Element(1), new Element(2), new Element(3)]; - IEnumerable enumerable2 = [new Element(3), new Element(2), new Element(1)]; + IEnumerable enumerable1 = EnumerableOf(new Element(1), new Element(2), new Element(3)); + IEnumerable enumerable2 = EnumerableOf(new Element(3), new Element(2), new Element(1)); // When int hashCode1 = enumerable1.GetContentHashCode(); @@ -265,7 +266,7 @@ public void GetContentHashCodeShouldProduceExpectedResultDifferent() public void IsEmptyShouldProduceExpectedResultTrueNonGeneric() { // Given - IEnumerable enumerable = Array.Empty(); + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsEmpty(); @@ -278,7 +279,7 @@ public void IsEmptyShouldProduceExpectedResultTrueNonGeneric() public void IsEmptyShouldProduceExpectedResultFalseNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element() }; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsEmpty(); @@ -291,7 +292,7 @@ public void IsEmptyShouldProduceExpectedResultFalseNonGeneric() public void IsEmptyShouldProduceExpectedResultTrue() { // Given - IEnumerable enumerable = []; + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsEmpty(); @@ -304,7 +305,7 @@ public void IsEmptyShouldProduceExpectedResultTrue() public void IsEmptyShouldProduceExpectedResultFalse() { // Given - IEnumerable enumerable = [new Element()]; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsEmpty(); @@ -317,7 +318,7 @@ public void IsEmptyShouldProduceExpectedResultFalse() public void IsNotEmptyShouldProduceExpectedResultTrueNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element() }; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsNotEmpty(); @@ -330,7 +331,7 @@ public void IsNotEmptyShouldProduceExpectedResultTrueNonGeneric() public void IsNotEmptyShouldProduceExpectedResultFalseNonGeneric() { // Given - IEnumerable enumerable = Array.Empty(); + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsNotEmpty(); @@ -343,7 +344,7 @@ public void IsNotEmptyShouldProduceExpectedResultFalseNonGeneric() public void IsNotEmptyShouldProduceExpectedResultTrue() { // Given - IEnumerable enumerable = [new Element()]; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsNotEmpty(); @@ -356,7 +357,7 @@ public void IsNotEmptyShouldProduceExpectedResultTrue() public void IsNotEmptyShouldProduceExpectedResultFalse() { // Given - IEnumerable enumerable = []; + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsNotEmpty(); @@ -369,7 +370,7 @@ public void IsNotEmptyShouldProduceExpectedResultFalse() public void IsSingleShouldProduceExpectedResultTrueNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element() }; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsSingle(); @@ -382,7 +383,7 @@ public void IsSingleShouldProduceExpectedResultTrueNonGeneric() public void IsSingleShouldProduceExpectedResultFalseWhenEmptyNonGeneric() { // Given - IEnumerable enumerable = Array.Empty(); + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsSingle(); @@ -395,7 +396,7 @@ public void IsSingleShouldProduceExpectedResultFalseWhenEmptyNonGeneric() public void IsSingleShouldProduceExpectedResultFalseWhenMoreThanOneElementNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element(), new Element() }; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsSingle(); @@ -408,7 +409,7 @@ public void IsSingleShouldProduceExpectedResultFalseWhenMoreThanOneElementNonGen public void IsSingleShouldProduceExpectedResultTrue() { // Given - IEnumerable enumerable = [new Element()]; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsSingle(); @@ -421,7 +422,7 @@ public void IsSingleShouldProduceExpectedResultTrue() public void IsSingleShouldProduceExpectedResultFalseWhenEmpty() { // Given - IEnumerable enumerable = []; + IEnumerable enumerable = EmptyEnumerable(); // When bool result = enumerable.IsSingle(); @@ -434,7 +435,7 @@ public void IsSingleShouldProduceExpectedResultFalseWhenEmpty() public void IsSingleShouldProduceExpectedResultFalseWhenMoreThanOneElement() { // Given - IEnumerable enumerable = [new Element(), new Element()]; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsSingle(); @@ -447,7 +448,7 @@ public void IsSingleShouldProduceExpectedResultFalseWhenMoreThanOneElement() public void IsCountEvenShouldProduceExpectedResultTrueNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element(), new Element() }; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsCountEven(); @@ -460,7 +461,7 @@ public void IsCountEvenShouldProduceExpectedResultTrueNonGeneric() public void IsCountEvenShouldProduceExpectedResultFalseNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element() }; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsCountEven(); @@ -473,7 +474,7 @@ public void IsCountEvenShouldProduceExpectedResultFalseNonGeneric() public void IsCountEvenShouldProduceExpectedResultTrue() { // Given - IEnumerable enumerable = [new Element(), new Element()]; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsCountEven(); @@ -486,7 +487,7 @@ public void IsCountEvenShouldProduceExpectedResultTrue() public void IsCountEvenShouldProduceExpectedResultFalse() { // Given - IEnumerable enumerable = [new Element()]; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsCountEven(); @@ -499,7 +500,7 @@ public void IsCountEvenShouldProduceExpectedResultFalse() public void IsCountOddShouldProduceExpectedResultTrueNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element() }; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsCountOdd(); @@ -512,7 +513,7 @@ public void IsCountOddShouldProduceExpectedResultTrueNonGeneric() public void IsCountOddShouldProduceExpectedResultFalseNonGeneric() { // Given - IEnumerable enumerable = new[] { new Element(), new Element() }; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsCountOdd(); @@ -525,7 +526,7 @@ public void IsCountOddShouldProduceExpectedResultFalseNonGeneric() public void IsCountOddShouldProduceExpectedResultTrue() { // Given - IEnumerable enumerable = [new Element()]; + IEnumerable enumerable = EnumerableOf(new Element()); // When bool result = enumerable.IsCountOdd(); @@ -538,7 +539,7 @@ public void IsCountOddShouldProduceExpectedResultTrue() public void IsCountOddShouldProduceExpectedResultFalse() { // Given - IEnumerable enumerable = [new Element(), new Element()]; + IEnumerable enumerable = EnumerableOf(new Element(), new Element()); // When bool result = enumerable.IsCountOdd(); @@ -551,7 +552,7 @@ public void IsCountOddShouldProduceExpectedResultFalse() public void JoinToStringShouldProduceExpectedResultWithDefaultSeparatorNonGeneric() { // Given - IEnumerable enumerable = new object[] { 1, 2, 3, 4.5, true, false }; + IEnumerable enumerable = EnumerableOf(1, 2, 3, 4.5, true, false); const string expected = "1, 2, 3, 4.5, True, False"; // When @@ -565,7 +566,7 @@ public void JoinToStringShouldProduceExpectedResultWithDefaultSeparatorNonGeneri public void JoinToStringShouldProduceExpectedResultWithCustomSeparatorNonGeneric() { // Given - IEnumerable enumerable = new object[] { 1, 2, 3, 4.5, true, false }; + IEnumerable enumerable = EnumerableOf(1, 2, 3, 4.5, true, false); const string expected = "1 *$ 2 *$ 3 *$ 4.5 *$ True *$ False"; // When @@ -579,7 +580,7 @@ public void JoinToStringShouldProduceExpectedResultWithCustomSeparatorNonGeneric public void JoinToStringShouldProduceExpectedResultWithDefaultSeparator() { // Given - IEnumerable enumerable = [1, 2, 3, 4.5, true, false]; + IEnumerable enumerable = EnumerableOf(1, 2, 3, 4.5, true, false); const string expected = "1, 2, 3, 4.5, True, False"; // When @@ -593,7 +594,7 @@ public void JoinToStringShouldProduceExpectedResultWithDefaultSeparator() public void JoinToStringShouldProduceExpectedResultWithCustomSeparator() { // Given - IEnumerable enumerable = [1, 2, 3, 4.5, true, false]; + IEnumerable enumerable = EnumerableOf(1, 2, 3, 4.5, true, false); const string expected = "1 *$ 2 *$ 3 *$ 4.5 *$ True *$ False"; // When @@ -607,7 +608,7 @@ public void JoinToStringShouldProduceExpectedResultWithCustomSeparator() public void LastOrNoneShouldReturnNoneWhenEnumerableIsEmpty() { // Given - IEnumerable elements = []; + IEnumerable elements = EmptyEnumerable(); Optional expected = Optional.None; // When @@ -621,7 +622,7 @@ public void LastOrNoneShouldReturnNoneWhenEnumerableIsEmpty() public void LastOrNoneShouldReturnLastElementWhenCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = 3; // When @@ -635,7 +636,7 @@ public void LastOrNoneShouldReturnLastElementWhenCollectionIsNotEmpty() public void LastOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = 3; // When @@ -649,7 +650,7 @@ public void LastOrNoneShouldReturnFirstElementMatchingPredicateWhenCollectionIsN public void LastOrNoneShouldReturnNoneWhenNoElementMatchesPredicateAndCollectionIsNotEmpty() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Optional expected = Optional.None; // When @@ -666,7 +667,7 @@ public void NoneShouldProduceExpectedResultTrue() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 456, Guid.NewGuid()); Record element3 = new("xyz", 789, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.None(element => element.Number == 0); @@ -682,7 +683,7 @@ public void NoneShouldProduceExpectedResultFalseAny() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 456, Guid.NewGuid()); Record element3 = new("xyz", 0, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.None(element => element.Number == 0); @@ -698,7 +699,7 @@ public void NoneShouldProduceExpectedResultFalseAll() Record element1 = new("abc", 0, Guid.NewGuid()); Record element2 = new("def", 0, Guid.NewGuid()); Record element3 = new("xyz", 0, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); // When bool result = elements.None(element => element.Number == 0); @@ -725,7 +726,7 @@ public void SequenceEqualOrNullShouldReturnTrueWhenCurrentAndOtherEnumerablesAre public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsNotNullAndOtherEnumerableIsNull() { // Given - IEnumerable enumerable = [1, 2, 3]; + IEnumerable enumerable = EnumerableOf(1, 2, 3); IEnumerable? other = null; // When @@ -740,7 +741,7 @@ public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsNullAndOth { // Given IEnumerable? enumerable = null; - IEnumerable other = [1, 2, 3]; + IEnumerable other = EnumerableOf(1, 2, 3); // When bool result = enumerable.SequenceEqualOrNull(other); @@ -753,8 +754,9 @@ public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsNullAndOth public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsEqualToTheOtherEnumerable() { // Given - IEnumerable? enumerable = [1, 2, 3]; - IEnumerable other = [1, 2, 3]; + // ReSharper disable once VariableCanBeNotNullable : THIS IS DELIBERATE! + IEnumerable? enumerable = EnumerableOf(1, 2, 3); + IEnumerable other = EnumerableOf(1, 2, 3); // When bool result = enumerable.SequenceEqualOrNull(other); @@ -767,8 +769,9 @@ public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsEqualToThe public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsNotEqualToTheOtherEnumerable() { // Given - IEnumerable? enumerable = [1, 2, 3]; - IEnumerable other = [3, 2, 1]; + // ReSharper disable once VariableCanBeNotNullable : THIS IS DELIBERATE! + IEnumerable? enumerable = EnumerableOf(1, 2, 3); + IEnumerable other = EnumerableOf(3, 2, 1); // When bool result = enumerable.SequenceEqualOrNull(other); @@ -781,7 +784,7 @@ public void SequenceEqualOrNullShouldReturnTrueWhenCurrentEnumerableIsNotEqualTo public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElements() { // Given - IEnumerable elements = []; + IEnumerable elements = EmptyEnumerable(); Result> expected = Optional.None.ToResult(); // When @@ -795,7 +798,7 @@ public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElements( public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleElement() { // Given - IEnumerable elements = [1]; + IEnumerable elements = EnumerableOf(1); Result> expected = Optional.Some(1).ToResult(); // When @@ -809,7 +812,7 @@ public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleEleme public void SingleOrNoneShouldReturnFailureSomeWhenEnumerableContainsMoreThanOneElement() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Failure> expected = Result>.Failure(new InvalidOperationException("Sequence contains more than one matching element")); // When @@ -826,7 +829,7 @@ public void SingleOrNoneShouldReturnFailureSomeWhenEnumerableContainsMoreThanOne public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElementsMatchingPredicate() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Result> expected = Optional.None.ToResult(); // When @@ -840,7 +843,7 @@ public void SingleOrNoneShouldReturnSuccessNoneWhenEnumerableContainsNoElementsM public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleElementMatchingPredicate() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Result> expected = Optional.Some(1).ToResult(); // When @@ -854,7 +857,7 @@ public void SingleOrNoneShouldReturnSuccessSomeWhenEnumerableContainsSingleEleme public void SingleOrNoneShouldReturnFailureSomeWhenEnumerableContainsMoreThanOneElementMatchingPredidate() { // Given - IEnumerable elements = [1, 2, 3]; + IEnumerable elements = EnumerableOf(1, 2, 3); Failure> expected = Result>.Failure(new InvalidOperationException("Sequence contains more than one matching element")); // When @@ -874,7 +877,7 @@ public void SumShouldProduceExpectedResult() static T SumProxy(IEnumerable enumerable) where T : INumberBase => enumerable.Sum(); // Given - IEnumerable elements = [12.34m, 34.56m, 56.78m]; + IEnumerable elements = EnumerableOf(12.34m, 34.56m, 56.78m); const decimal expected = 103.68m; // When @@ -891,7 +894,7 @@ public void SumWithSelectorShouldProduceExpectedResult() Numeric element1 = new(1234.567m); Numeric element2 = new(890.1234m); Numeric element3 = new(56.78901m); - IEnumerable> elements = [element1, element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); const decimal expected = 2181.47941m; // When @@ -908,8 +911,8 @@ public void WhereNotShouldProduceExpectedResult() Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 456, Guid.NewGuid()); Record element3 = new("xyz", 789, Guid.NewGuid()); - IEnumerable> elements = [element1, element2, element3]; - IEnumerable> expected = [element2, element3]; + IEnumerable> elements = EnumerableOf(element1, element2, element3); + IEnumerable> expected = EnumerableOf(element2, element3); // When IEnumerable> actual = elements.WhereNot(element => element.Number == 123); @@ -924,8 +927,8 @@ public void WhereNotNullShouldProduceExpectedResultClass() // Given Record element1 = new("abc", 123, Guid.NewGuid()); Record element2 = new("def", 456, Guid.NewGuid()); - IEnumerable?> elements = [element1, element2, null]; - IEnumerable> expected = [element1, element2]; + IEnumerable?> elements = EnumerableOf(element1, element2, null); + IEnumerable> expected = EnumerableOf(element1, element2); // When IEnumerable> actual = elements.WhereNotNull(); @@ -938,8 +941,8 @@ public void WhereNotNullShouldProduceExpectedResultClass() public void WhereNotNullShouldProduceExpectedResultStruct() { // Given - IEnumerable elements = [1, 2, null, 3, null, 4, 5]; - IEnumerable expected = [1, 2, 3, 4, 5]; + IEnumerable elements = EnumerableOf(1, 2, null, 3, null, 4, 5); + IEnumerable expected = EnumerableOf(1, 2, 3, 4, 5); // When IEnumerable actual = elements.WhereNotNull(); @@ -952,7 +955,7 @@ public void WhereNotNullShouldProduceExpectedResultStruct() public void ToCollectionStringShouldProduceExpectedResultObjectNonGeneric() { // Given - IEnumerable values = new object[] { 123, "abc", true, 123.456 }; + IEnumerable values = EnumerableOf(123, "abc", true, 123.456); const string expected = "[123, abc, True, 123.456]"; // When @@ -966,7 +969,7 @@ public void ToCollectionStringShouldProduceExpectedResultObjectNonGeneric() public void ToCollectionStringShouldProduceExpectedResultStringNonGeneric() { // Given - IEnumerable values = new[] { "abc", "xyz", "123" }; + IEnumerable values = EnumerableOf("abc", "xyz", "123"); const string expected = "[abc, xyz, 123]"; // When @@ -980,7 +983,7 @@ public void ToCollectionStringShouldProduceExpectedResultStringNonGeneric() public void ToCollectionStringShouldProduceExpectedResultInt32NonGeneric() { // Given - IEnumerable values = new[] { 0, 1, 12, 123, 1234, -1, -12, -123, -1234 }; + IEnumerable values = EnumerableOf(0, 1, 12, 123, 1234, -1, -12, -123, -1234); const string expected = "[0, 1, 12, 123, 1234, -1, -12, -123, -1234]"; // When @@ -994,7 +997,7 @@ public void ToCollectionStringShouldProduceExpectedResultInt32NonGeneric() public void ToCollectionStringShouldProduceExpectedResultObject() { // Given - object[] values = [123, "abc", true, 123.456]; + IEnumerable values = EnumerableOf(123, "abc", true, 123.456); const string expected = "[123, abc, True, 123.456]"; // When @@ -1008,7 +1011,7 @@ public void ToCollectionStringShouldProduceExpectedResultObject() public void ToCollectionStringShouldProduceExpectedResultString() { // Given - string[] values = ["abc", "xyz", "123"]; + IEnumerable values = EnumerableOf("abc", "xyz", "123"); const string expected = "[abc, xyz, 123]"; // When @@ -1022,7 +1025,7 @@ public void ToCollectionStringShouldProduceExpectedResultString() public void ToCollectionStringShouldProduceExpectedResultInt32() { // Given - int[] values = [0, 1, 12, 123, 1234, -1, -12, -123, -1234]; + IEnumerable values = EnumerableOf(0, 1, 12, 123, 1234, -1, -12, -123, -1234); const string expected = "[0, 1, 12, 123, 1234, -1, -12, -123, -1234]"; // When @@ -1036,7 +1039,7 @@ public void ToCollectionStringShouldProduceExpectedResultInt32() public void ToCollectionStringShouldProduceExpectedResultInt32IFormattable() { // Given - int[] values = [0, 1, 12, 123, 1234, -1, -12, -123, -1234]; + IEnumerable values = EnumerableOf(0, 1, 12, 123, 1234, -1, -12, -123, -1234); const string expected = "[£0.00, £1.00, £12.00, £123.00, £1,234.00, -£1.00, -£12.00, -£123.00, -£1,234.00]"; // When diff --git a/OnixLabs.Core.UnitTests/ObjectExtensionTests.cs b/OnixLabs.Core.UnitTests/ObjectExtensionTests.cs index f484d9f..82494eb 100644 --- a/OnixLabs.Core.UnitTests/ObjectExtensionTests.cs +++ b/OnixLabs.Core.UnitTests/ObjectExtensionTests.cs @@ -327,7 +327,7 @@ public async Task ToOptionalAsyncShouldProduceExpectedResultWhenUsingNonNullRefe const string expected = "abc"; // When - Optional optional = await Task.FromResult(expected).ToOptionalAsync(); + Optional optional = await Task.FromResult(expected).ToOptionalAsync(token: TestContext.Current.CancellationToken); // Then Some some = Assert.IsType>(optional); @@ -341,7 +341,7 @@ public async Task ToOptionalAsyncShouldProduceExpectedResultWhenUsingNullReferen const string? expected = null; // When - Optional optional = await Task.FromResult(expected).ToOptionalAsync(); + Optional optional = await Task.FromResult(expected).ToOptionalAsync(token: TestContext.Current.CancellationToken); // Then Assert.IsType>(optional); @@ -354,7 +354,7 @@ public async Task ToOptionalAsyncShouldProduceExpectedResultWhenUsingNonNullValu const int expected = 123; // When - Optional optional = await Task.FromResult(expected).ToOptionalAsync(); + Optional optional = await Task.FromResult(expected).ToOptionalAsync(token: TestContext.Current.CancellationToken); // Then Some some = Assert.IsType>(optional); @@ -368,7 +368,7 @@ public async Task ToOptionalAsyncShouldProduceExpectedResultWhenUsingNullValueTy int? expected = null; // When - Optional optional = await Task.FromResult(expected).ToOptionalAsync(); + Optional optional = await Task.FromResult(expected).ToOptionalAsync(token: TestContext.Current.CancellationToken); // Then Assert.IsType>(optional); @@ -396,7 +396,7 @@ public async Task ToSuccessAsyncShouldProduceTheExpectedResult() // When Task task = Task.FromResult(expected); - Result result = await task.ToSuccessAsync(); + Result result = await task.ToSuccessAsync(token: TestContext.Current.CancellationToken); // Then Success success = Assert.IsType>(result); diff --git a/OnixLabs.Core.UnitTests/PreconditionTests.cs b/OnixLabs.Core.UnitTests/PreconditionTests.cs index 855116b..18284a3 100644 --- a/OnixLabs.Core.UnitTests/PreconditionTests.cs +++ b/OnixLabs.Core.UnitTests/PreconditionTests.cs @@ -332,7 +332,7 @@ public void RequireIsFailureShouldThrowAnInvalidOperationExceptionWhenTheResultI Exception exception = Assert.Throws(() => RequireIsFailure(result)); // Then - Assert.Equal("Argument must be a Failure state.", exception.Message); + Assert.Equal("Argument must be a Failure state. (Parameter 'result')", exception.Message); } [Fact(DisplayName = "RequireIsFailure should return a Failure when the result is a failure state")] @@ -358,7 +358,7 @@ public void RequireIsSuccessShouldThrowAnInvalidOperationExceptionWhenTheResultI Exception exception = Assert.Throws(() => RequireIsSuccess(result)); // Then - Assert.Equal("Argument must be a Success state.", exception.Message); + Assert.Equal("Argument must be a Success state. (Parameter 'result')", exception.Message); } [Fact(DisplayName = "RequireIsSuccess should return a Success when the result is a success state")] @@ -384,7 +384,7 @@ public void RequireIsFailureTShouldThrowAnInvalidOperationExceptionWhenTheResult Exception exception = Assert.Throws(() => RequireIsFailure(result)); // Then - Assert.Equal("Argument must be a Failure state.", exception.Message); + Assert.Equal("Argument must be a Failure state. (Parameter 'result')", exception.Message); } [Fact(DisplayName = "RequireIsFailure should return a Failure when the result is a failure state")] @@ -410,7 +410,7 @@ public void RequireIsSuccessTShouldThrowAnInvalidOperationExceptionWhenTheResult Exception exception = Assert.Throws(() => RequireIsSuccess(result)); // Then - Assert.Equal("Argument must be a Success state.", exception.Message); + Assert.Equal("Argument must be a Success state. (Parameter 'result')", exception.Message); } [Fact(DisplayName = "RequireIsSuccess should return a Success when the result is a success state")] @@ -436,7 +436,7 @@ public void RequireIsNoneShouldThrowAnInvalidOperationExceptionWhenTheOptionalIs Exception exception = Assert.Throws(() => RequireIsNone(optional)); // Then - Assert.Equal("Argument must be a None value.", exception.Message); + Assert.Equal("Argument must be a None value. (Parameter 'optional')", exception.Message); } [Fact(DisplayName = "RequireIsNone should return a None when the optional is a None value")] @@ -462,7 +462,7 @@ public void RequireIsSomeShouldThrowAnInvalidOperationExceptionWhenTheOptionalIs Exception exception = Assert.Throws(() => RequireIsSome(optional)); // Then - Assert.Equal("Argument must be a Some value.", exception.Message); + Assert.Equal("Argument must be a Some value. (Parameter 'optional')", exception.Message); } [Fact(DisplayName = "RequireIsSome should return a Some when the optional is a Some value")] @@ -485,7 +485,7 @@ public void RequireWithinRangeInclusiveShouldThrowArgumentOutOfRangeExceptionWhe Exception exception = Assert.Throws(() => RequireWithinRangeInclusive(1, 2, 3)); // Then - Assert.Equal("Argument must be within range.", exception.Message); + Assert.Equal("Argument must be within range. (Parameter '1')", exception.Message); } [Fact(DisplayName = "RequireWithinRangeInclusive should throw an ArgumentOutOfRangeException when the value falls above the specified range")] @@ -495,7 +495,7 @@ public void RequireWithinRangeInclusiveShouldThrowArgumentOutOfRangeExceptionWhe Exception exception = Assert.Throws(() => RequireWithinRangeInclusive(4, 2, 3)); // Then - Assert.Equal("Argument must be within range.", exception.Message); + Assert.Equal("Argument must be within range. (Parameter '4')", exception.Message); } [Fact(DisplayName = "RequireWithinRangeInclusive should not throw an ArgumentOutOfRangeException when the value is exactly the minimum value")] @@ -544,7 +544,7 @@ public void RequireWithinRangeExclusiveShouldThrowArgumentOutOfRangeExceptionWhe Exception exception = Assert.Throws(() => RequireWithinRangeExclusive(2, 2, 4)); // Then - Assert.Equal("Argument must be within range.", exception.Message); + Assert.Equal("Argument must be within range. (Parameter '2')", exception.Message); } [Fact(DisplayName = "RequireWithinRangeExclusive should throw an ArgumentOutOfRangeException when the value falls above the specified range")] @@ -554,7 +554,7 @@ public void RequireWithinRangeExclusiveShouldThrowArgumentOutOfRangeExceptionWhe Exception exception = Assert.Throws(() => RequireWithinRangeExclusive(4, 2, 4)); // Then - Assert.Equal("Argument must be within range.", exception.Message); + Assert.Equal("Argument must be within range. (Parameter '4')", exception.Message); } [Fact(DisplayName = "RequireWithinRangeExclusive should not throw an ArgumentOutOfRangeException when the value falls between the specified range")] @@ -577,7 +577,7 @@ public void RequireNotNullShouldThrowArgumentNullExceptionWhenConditionIsNull() Exception exception = Assert.Throws(() => RequireNotNull(null)); // Then - Assert.Equal("Argument must not be null.", exception.Message); + Assert.Equal("Argument must not be null. (Parameter 'null')", exception.Message); } [Fact(DisplayName = "RequireNotNull should not throw an InvalidOperationException when the condition is not null")] @@ -599,7 +599,7 @@ public void RequireNotNullOfValueTypeShouldThrowInvalidOperationExceptionWhenCon // Then Assert.Equal(0, actual); - Assert.Equal("Argument must not be null.", exception.Message); + Assert.Equal("Argument must not be null. (Parameter 'expected')", exception.Message); } [Fact(DisplayName = "RequireNotNull of ValueType should not throw an InvalidOperationException when the condition is not null")] @@ -622,7 +622,7 @@ public void RequireNotNullOrEmptyShouldThrowArgumentExceptionWhenValueIsNull() Exception exception = Assert.Throws(() => RequireNotNullOrEmpty(null)); // Then - Assert.Equal("Argument must not be null or empty.", exception.Message); + Assert.Equal("Argument must not be null or empty. (Parameter 'null')", exception.Message); } [Fact(DisplayName = "RequireNotNullOrEmpty should throw an ArgumentException when the value is empty")] @@ -632,7 +632,7 @@ public void RequireNotNullOrEmptyShouldThrowArgumentExceptionWhenValueIsEmpty() Exception exception = Assert.Throws(() => RequireNotNullOrEmpty(string.Empty)); // Then - Assert.Equal("Argument must not be null or empty.", exception.Message); + Assert.Equal("Argument must not be null or empty. (Parameter 'string.Empty')", exception.Message); } [Fact(DisplayName = "RequireNotNullOrEmpty should return the argument value when the value is not null and not empty")] @@ -655,7 +655,7 @@ public void RequireNotNullOrWhiteSpaceShouldThrowArgumentExceptionWhenValueIsNul Exception exception = Assert.Throws(() => RequireNotNullOrWhiteSpace(null)); // Then - Assert.Equal("Argument must not be null or whitespace.", exception.Message); + Assert.Equal("Argument must not be null or whitespace. (Parameter 'null')", exception.Message); } [Fact(DisplayName = "RequireNotNullOrWhiteSpace should throw an ArgumentException when the value is whitespace")] @@ -665,7 +665,7 @@ public void RequireNotNullOrWhiteSpaceShouldThrowArgumentExceptionWhenValueIsWhi Exception exception = Assert.Throws(() => RequireNotNullOrWhiteSpace(" ")); // Then - Assert.Equal("Argument must not be null or whitespace.", exception.Message); + Assert.Equal("Argument must not be null or whitespace. (Parameter '\" \"')", exception.Message); } [Fact(DisplayName = "RequireNotNullOrWhiteSpace should return the argument value when the value is not null and not whitespace")] @@ -688,7 +688,7 @@ public void RequireIsDefinedShouldThrowArgumentOutOfRangeExceptionWhenSpecifiedE Exception exception = Assert.Throws(() => RequireIsDefined((Shape)2)); // Then - Assert.Equal("Invalid Shape enum value: 2. Valid values include: Square, Circle.", exception.Message); + Assert.Equal("Invalid Shape enum value: 2. Valid values include: Square, Circle. (Parameter '(Shape)2')", exception.Message); } [Fact(DisplayName = "RequireIsDefined should not throw an ArgumentOutOfRangeException when the specified enum value is defined")] diff --git a/OnixLabs.Core.UnitTests/ResultExtensionTests.cs b/OnixLabs.Core.UnitTests/ResultExtensionTests.cs index e8c7d06..2def317 100644 --- a/OnixLabs.Core.UnitTests/ResultExtensionTests.cs +++ b/OnixLabs.Core.UnitTests/ResultExtensionTests.cs @@ -29,7 +29,7 @@ public async Task ResultSuccessGetExceptionOrDefaultAsyncShouldProduceExpectedRe Result result = Result.Success(); // When - Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(); + Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Null(actual); @@ -42,7 +42,7 @@ public async Task ResultSuccessGetExceptionOrDefaultAsyncWithDefaultValueShouldP Result result = Result.Success(); // When - Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(FailureException); + Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(FailureException, token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -55,7 +55,8 @@ public async Task ResultSuccessGetExceptionOrThrowAsyncShouldProduceExpectedResu Result result = Result.Success(); // When - Exception exception = await Assert.ThrowsAsync(async () => await Task.FromResult(result).GetExceptionOrThrowAsync()); + Exception exception = await Assert.ThrowsAsync(async () => + await Task.FromResult(result).GetExceptionOrThrowAsync(token: TestContext.Current.CancellationToken)); // Then Assert.Equal("The current result is not in a failure state.", exception.Message); @@ -68,7 +69,7 @@ public async Task ResultFailureGetExceptionOrDefaultAsyncShouldProduceExpectedRe Result result = Result.Failure(FailureException); // When - Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(); + Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -81,7 +82,7 @@ public async Task ResultFailureGetExceptionOrDefaultAsyncWithDefaultValueShouldP Result result = Result.Failure(FailureException); // When - Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception")); + Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception"), token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -94,7 +95,7 @@ public async Task ResultFailureGetExceptionOrThrowAsyncShouldProduceExpectedResu Result result = Result.Failure(FailureException); // When - Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync(); + Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -107,7 +108,7 @@ public async Task ResultOfTSuccessGetExceptionOrDefaultAsyncShouldProduceExpecte Result result = Result.Success(123); // When - Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(); + Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Null(actual); @@ -120,7 +121,7 @@ public async Task ResultOfTSuccessGetExceptionOrDefaultAsyncWithDefaultValueShou Result result = Result.Success(123); // When - Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(FailureException); + Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(FailureException, token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -133,7 +134,8 @@ public async Task ResultOfTSuccessGetExceptionOrThrowAsyncShouldProduceExpectedR Result result = Result.Success(123); // When - Exception exception = await Assert.ThrowsAsync(async () => await Task.FromResult(result).GetExceptionOrThrowAsync()); + Exception exception = await Assert.ThrowsAsync(async () => + await Task.FromResult(result).GetExceptionOrThrowAsync(token: TestContext.Current.CancellationToken)); // Then Assert.Equal("The current result is not in a failure state.", exception.Message); @@ -146,7 +148,7 @@ public async Task ResultOfTFailureGetExceptionOrDefaultAsyncShouldProduceExpecte Result result = Result.Failure(FailureException); // When - Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(); + Exception? actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -159,7 +161,7 @@ public async Task ResultOfTFailureGetExceptionOrDefaultAsyncWithDefaultValueShou Result result = Result.Failure(FailureException); // When - Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception")); + Exception actual = await Task.FromResult(result).GetExceptionOrDefaultAsync(new Exception("unexpected exception"), token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -172,7 +174,7 @@ public async Task ResultOfTFailureGetExceptionOrThrowAsyncShouldProduceExpectedR Result result = Result.Failure(FailureException); // When - Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync(); + Exception actual = await Task.FromResult(result).GetExceptionOrThrowAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(FailureException, actual); @@ -184,12 +186,12 @@ public async Task ResultGetValueOrDefaultAsyncShouldReturnResultValueWhenResultI // Given const int expectedNumber = 123; const string expectedText = "abc"; - Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber)); - Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText)); + Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber), TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText), TestContext.Current.CancellationToken); // When - int actualNumber = await numberTask.GetValueOrDefaultAsync(); - string? actualText = await textTask.GetValueOrDefaultAsync(); + int actualNumber = await numberTask.GetValueOrDefaultAsync(token: TestContext.Current.CancellationToken); + string? actualText = await textTask.GetValueOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -202,12 +204,12 @@ public async Task ResultGetValueOrDefaultAsyncShouldReturnResultValueWhenResultI public async Task ResultGetValueOrDefaultAsyncShouldReturnDefaultWhenResultIsFailure() { // Given - Task> numberTask = Result.OfAsync(() => throw FailureException); - Task> textTask = Result.OfAsync(() => throw FailureException); + Task> numberTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); // When - int actualNumber = await numberTask.GetValueOrDefaultAsync(); - string? actualText = await textTask.GetValueOrDefaultAsync(); + int actualNumber = await numberTask.GetValueOrDefaultAsync(token: TestContext.Current.CancellationToken); + string? actualText = await textTask.GetValueOrDefaultAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(0, actualNumber); @@ -220,13 +222,13 @@ public async Task ResultGetValueOrDefaultAsyncWithDefaultValueShouldReturnResult // Given const int expectedNumber = 123; const string expectedText = "abc"; - Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber)); - Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText)); + Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber), TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText), TestContext.Current.CancellationToken); // When - int actualNumber = await numberTask.GetValueOrDefaultAsync(456); + int actualNumber = await numberTask.GetValueOrDefaultAsync(456, token: TestContext.Current.CancellationToken); // ReSharper disable once VariableCanBeNotNullable - string? actualText = await textTask.GetValueOrDefaultAsync("xyz"); + string? actualText = await textTask.GetValueOrDefaultAsync("xyz", token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -241,12 +243,12 @@ public async Task ResultGetValueOrDefaultAsyncWithDefaultValueShouldReturnDefaul // Given const int expectedNumber = 456; const string expectedText = "abc"; - Task> numberTask = Result.OfAsync(() => throw FailureException); - Task> textTask = Result.OfAsync(() => throw FailureException); + Task> numberTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); // When - int actualNumber = await numberTask.GetValueOrDefaultAsync(expectedNumber); - string actualText = await textTask.GetValueOrDefaultAsync(expectedText); + int actualNumber = await numberTask.GetValueOrDefaultAsync(expectedNumber, token: TestContext.Current.CancellationToken); + string actualText = await textTask.GetValueOrDefaultAsync(expectedText, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -261,12 +263,12 @@ public async Task ResultGetValueOrThrowAsyncShouldReturnResultValueWhenResultIsS // Given const int expectedNumber = 123; const string expectedText = "abc"; - Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber)); - Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText)); + Task> numberTask = Result.OfAsync(async () => await Task.FromResult(expectedNumber), TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(async () => await Task.FromResult(expectedText), TestContext.Current.CancellationToken); // When - int actualNumber = await numberTask.GetValueOrThrowAsync(); - string actualText = await textTask.GetValueOrThrowAsync(); + int actualNumber = await numberTask.GetValueOrThrowAsync(token: TestContext.Current.CancellationToken); + string actualText = await textTask.GetValueOrThrowAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -279,12 +281,15 @@ public async Task ResultGetValueOrThrowAsyncShouldReturnResultValueWhenResultIsS public async Task ResultGetValueOrThrowAsyncShouldReturnDefaultWhenResultIsFailure() { // Given - Task> numberTask = Result.OfAsync(() => throw FailureException); - Task> textTask = Result.OfAsync(() => throw FailureException); + Task> numberTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); + Task> textTask = Result.OfAsync(() => throw FailureException, TestContext.Current.CancellationToken); // When - Exception numberException = await Assert.ThrowsAsync(async () => await numberTask.GetValueOrThrowAsync()); - Exception textException = await Assert.ThrowsAsync(async () => await textTask.GetValueOrThrowAsync()); + Exception numberException = await Assert.ThrowsAsync(async () => + await numberTask.GetValueOrThrowAsync(token: TestContext.Current.CancellationToken)); + + Exception textException = await Assert.ThrowsAsync(async () => + await textTask.GetValueOrThrowAsync(token: TestContext.Current.CancellationToken)); // Then Assert.Equal(numberException, FailureException); @@ -351,8 +356,8 @@ public async Task ResultGetValueOrNoneAsyncShouldReturnOptionalValueWhenResultIs Result textResult = expectedText; // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(Optional.Of(expectedNumber), actualNumber); @@ -367,8 +372,8 @@ public async Task ResultGetValueOrNoneAsyncShouldReturnNoneWhenResultIsSuccessAn Result textResult = Result.Success(null!); // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(Optional.None, actualNumber); @@ -383,8 +388,8 @@ public async Task ResultGetValueOrNoneAsyncShouldReturnNoneWhenResultIsFailure() Result textResult = Result.Failure(FailureException); // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(Optional.None, actualNumber); @@ -455,8 +460,8 @@ public async Task ResultOptionalGetValueOrNoneAsyncShouldReturnOptionalValueWhen Result> textResult = expectedText; // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -473,8 +478,8 @@ public async Task ResultOptionalGetValueOrNoneAsyncShouldReturnNoneWhenResultIsS Result> textResult = expectedText; // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -491,8 +496,8 @@ public async Task ResultOptionalGetValueOrNoneAsyncShouldReturnNoneWhenResultIsF Result> textResult = Result>.Failure(FailureException); // When - Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(); - Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(); + Optional actualNumber = await Task.FromResult(numberResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); + Optional actualText = await Task.FromResult(textResult).GetValueOrNoneAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -559,8 +564,8 @@ public async Task ResultGetOptionalValueOrThrowAsyncShouldReturnOptionalValueWhe Result> textResult = Optional.Some(expectedText); // When - int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync(); - string actualText = await Task.FromResult(textResult).GetOptionalValueOrThrowAsync(); + int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken); + string actualText = await Task.FromResult(textResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -575,8 +580,11 @@ public async Task ResultGetOptionalValueOrThrowAsyncShouldThrowInvalidOperationE Result> textResult = Optional.None; // When - Exception numberException = await Assert.ThrowsAsync(async () => await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync()); - Exception textException = await Assert.ThrowsAsync(async () => await Task.FromResult(textResult).GetOptionalValueOrThrowAsync()); + Exception numberException = await Assert.ThrowsAsync(async () => + await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken)); + + Exception textException = await Assert.ThrowsAsync(async () => + await Task.FromResult(textResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken)); // Then Assert.Equal("Optional value of type System.Int32 is not present.", numberException.Message); @@ -591,8 +599,11 @@ public async Task ResultGetOptionalValueOrThrowAsyncShouldThrowInvalidOperationE Result> textResult = Result>.Failure(new Exception("Result has failed.")); // When - Exception numberException = await Assert.ThrowsAsync(async () => await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync()); - Exception textException = await Assert.ThrowsAsync(async () => await Task.FromResult(textResult).GetOptionalValueOrThrowAsync()); + Exception numberException = await Assert.ThrowsAsync(async () => + await Task.FromResult(numberResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken)); + + Exception textException = await Assert.ThrowsAsync(async () => + await Task.FromResult(textResult).GetOptionalValueOrThrowAsync(token: TestContext.Current.CancellationToken)); // Then Assert.Equal("Result has failed.", numberException.Message); @@ -664,8 +675,8 @@ public async Task ResultGetOptionalValueOrDefaultAsyncShouldReturnOptionalValueW Result> textResult = Optional.Some(expectedText); // When - int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(456); - string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync("xyz"); + int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(456, token: TestContext.Current.CancellationToken); + string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync("xyz", token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -682,8 +693,8 @@ public async Task ResultGetOptionalValueOrDefaultAsyncShouldReturnDefaultValueWh Result> textResult = Optional.None; // When - int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(expectedNumber); - string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync(expectedText); + int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(expectedNumber, token: TestContext.Current.CancellationToken); + string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync(expectedText, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -700,8 +711,8 @@ public async Task ResultGetOptionalValueOrDefaultAsyncShouldReturnDefaultValueWh Result> textResult = Result>.Failure(new Exception("Result has failed.")); // When - int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(expectedNumber); - string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync(expectedText); + int actualNumber = await Task.FromResult(numberResult).GetOptionalValueOrDefaultAsync(expectedNumber, token: TestContext.Current.CancellationToken); + string actualText = await Task.FromResult(textResult).GetOptionalValueOrDefaultAsync(expectedText, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expectedNumber, actualNumber); @@ -717,7 +728,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, Failure); + await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -737,7 +748,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, Failure); + await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -757,7 +768,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateFuncTa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -777,7 +788,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateFuncTa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -797,7 +808,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateFuncCa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -817,7 +828,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateFuncCa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -837,7 +848,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -857,7 +868,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -877,7 +888,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -897,7 +908,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateAction bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -917,7 +928,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateFuncTa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -937,7 +948,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateFuncTa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -957,7 +968,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldInvokeSuccessDelegateFuncCa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -977,7 +988,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldInvokeFailureDelegateFuncCa bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -996,7 +1007,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, Failure); + string actual = await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1014,7 +1025,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, Failure); + string actual = await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1032,7 +1043,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1050,7 +1061,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1068,7 +1079,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1086,7 +1097,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1104,7 +1115,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1122,7 +1133,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1140,7 +1151,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1158,7 +1169,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1176,7 +1187,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1194,7 +1205,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1212,7 +1223,7 @@ public async Task TaskResultMatchAsyncOfSuccessShouldReturnResultFromSuccessDele const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1230,7 +1241,7 @@ public async Task TaskResultMatchAsyncOfFailureShouldReturnResultFromFailureDele const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1249,7 +1260,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, Failure); + await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1269,7 +1280,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, Failure); + await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1289,7 +1300,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1309,7 +1320,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1329,7 +1340,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1349,7 +1360,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1369,7 +1380,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1389,7 +1400,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1409,7 +1420,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1429,7 +1440,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateAct bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(Success, FailureAsync); + await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1449,7 +1460,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1469,7 +1480,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1489,7 +1500,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldInvokeSuccessDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.True(successCalled); @@ -1509,7 +1520,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldInvokeFailureDelegateFun bool failureCalled = false; // When - await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.False(successCalled); @@ -1528,7 +1539,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, Failure); + string actual = await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1546,7 +1557,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, Failure); + string actual = await Task.FromResult(result).MatchAsync(Success, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1564,7 +1575,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1582,7 +1593,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1600,7 +1611,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1618,7 +1629,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, Failure, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1636,7 +1647,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1654,7 +1665,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1672,7 +1683,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1690,7 +1701,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(Success, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1708,7 +1719,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1726,7 +1737,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1744,7 +1755,7 @@ public async Task TaskResultOfTMatchAsyncOfSuccessShouldReturnResultFromSuccessD const string expected = "Success"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1762,7 +1773,7 @@ public async Task TaskResultOfTMatchAsyncOfFailureShouldReturnResultFromFailureD const string expected = "Failure"; // When - string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync); + string actual = await Task.FromResult(result).MatchAsync(SuccessAsync, FailureAsync, token: TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1780,7 +1791,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateActi bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1798,7 +1809,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateA bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1816,7 +1827,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateFunc bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1834,7 +1845,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1852,7 +1863,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateFunc bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1870,7 +1881,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -1888,7 +1899,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateFunc bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -1912,7 +1923,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -1935,7 +1946,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateFunc bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -1959,7 +1970,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -1982,7 +1993,7 @@ public async Task TaskResultSelectAsyncOfSuccessShouldInvokeSelectorDelegateFunc bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2006,7 +2017,7 @@ public async Task TaskResultSelectAsyncOfFailureShouldNotInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2029,7 +2040,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateA bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2051,7 +2062,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2073,7 +2084,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2096,7 +2107,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2119,7 +2130,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2142,7 +2153,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2165,7 +2176,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2189,7 +2200,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(Selector); + Result actual = await Task.FromResult(result).SelectAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2212,7 +2223,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2236,7 +2247,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2259,7 +2270,7 @@ public async Task TaskResultOfTSelectAsyncOfSuccessShouldInvokeSelectorDelegateF bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2283,7 +2294,7 @@ public async Task TaskResultOfTSelectAsyncOfFailureShouldNotInvokeSelectorDelega bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2306,7 +2317,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2328,7 +2339,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2350,7 +2361,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2372,7 +2383,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2394,7 +2405,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2416,7 +2427,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2438,7 +2449,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2462,7 +2473,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2485,7 +2496,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2509,7 +2520,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2532,7 +2543,7 @@ public async Task TaskResultSelectManyAsyncOfSuccessShouldInvokeSelectorDelegate bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2556,7 +2567,7 @@ public async Task TaskResultSelectManyAsyncOfFailureShouldNotInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2579,7 +2590,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2602,7 +2613,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2625,7 +2636,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2648,7 +2659,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2671,7 +2682,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2694,7 +2705,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); @@ -2717,7 +2728,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2741,7 +2752,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(Selector); + Result actual = await Task.FromResult(result).SelectManyAsync(Selector, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2764,7 +2775,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2788,7 +2799,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2811,7 +2822,7 @@ public async Task TaskResultOfTSelectManyAsyncOfSuccessShouldInvokeSelectorDeleg bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2835,7 +2846,7 @@ public async Task TaskResultOfTSelectManyAsyncOfFailureShouldNotInvokeSelectorDe bool selectorInvoked = false; // When - Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync); + Result actual = await Task.FromResult(result).SelectManyAsync(SelectorAsync, token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2857,7 +2868,7 @@ public async Task ResultSuccessThrowAsyncShouldDoNothing() Result result = Result.Success(); // When / Then - await Task.FromResult(result).ThrowAsync(); + await Task.FromResult(result).ThrowAsync(token: TestContext.Current.CancellationToken); } [Fact(DisplayName = "Result Failure.Throw should throw Exception")] @@ -2867,7 +2878,7 @@ public async Task ResultFailureThrowAsyncShouldThrowException() Result result = Result.Failure(FailureException); // When / Then - await Assert.ThrowsAsync(async () => await Task.FromResult(result).ThrowAsync()); + await Assert.ThrowsAsync(async () => await Task.FromResult(result).ThrowAsync(token: TestContext.Current.CancellationToken)); } [Fact(DisplayName = "Result Success.ThrowAsync should do nothing")] @@ -2877,7 +2888,7 @@ public async Task ResultOfTSuccessThrowAsyncShouldDoNothing() Result result = Result.Success(123); // When / Then - await Task.FromResult(result).ThrowAsync(); + await Task.FromResult(result).ThrowAsync(token: TestContext.Current.CancellationToken); } [Fact(DisplayName = "Result Failure.ThrowAsync should throw Exception")] @@ -2887,7 +2898,7 @@ public async Task ResultOfTFailureThrowAsyncShouldThrowException() Result result = Result.Failure(FailureException); // When / Then - await Assert.ThrowsAsync(async () => await Task.FromResult(result).ThrowAsync()); + await Assert.ThrowsAsync(async () => await Task.FromResult(result).ThrowAsync(token: TestContext.Current.CancellationToken)); } [Fact(DisplayName = "Result Failure.ToTypedResultAsync should produce the expected result.")] @@ -2897,7 +2908,7 @@ public async Task ResultFailureToTypedResultAsyncShouldProduceExpectedResult() Failure result = Result.Failure(FailureException); // When - Result actual = await Task.FromResult(result).ToTypedResultAsync(); + Result actual = await Task.FromResult(result).ToTypedResultAsync(token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2911,7 +2922,7 @@ public async Task ResultOfTFailureToTypedResultAsyncShouldProduceExpectedResult( Failure result = Result.Failure(FailureException); // When - Result actual = await Task.FromResult(result).ToTypedResultAsync(); + Result actual = await Task.FromResult(result).ToTypedResultAsync(token: TestContext.Current.CancellationToken); // Then Assert.IsType>(actual); @@ -2925,10 +2936,10 @@ public async Task ResultOfTFailureToUntypedResultAsyncShouldProduceExpectedResul Failure result = Result.Failure(FailureException); // When - Result actual = await Task.FromResult(result).ToUntypedResultAsync(); + Result actual = await Task.FromResult(result).ToUntypedResultAsync(token: TestContext.Current.CancellationToken); // Then Assert.IsType(actual); - Assert.Equal("System.Exception: Failure", actual.GetExceptionOrThrow().ToString()); + Assert.StartsWith("System.Exception: Failure", actual.GetExceptionOrThrow().ToString()); } } diff --git a/OnixLabs.Core.UnitTests/ResultGenericTests.cs b/OnixLabs.Core.UnitTests/ResultGenericTests.cs index 8606e00..cce2a76 100644 --- a/OnixLabs.Core.UnitTests/ResultGenericTests.cs +++ b/OnixLabs.Core.UnitTests/ResultGenericTests.cs @@ -70,7 +70,7 @@ public void ResultOfShouldProduceExpectedFailureResult() public async Task ResultOfAsyncShouldProduceExpectedSuccessResult() { // Given / When - Result result = await Result.OfAsync(async () => await Task.FromResult(1)); + Result result = await Result.OfAsync(async () => await Task.FromResult(1), TestContext.Current.CancellationToken); // Then Assert.IsType>(result); @@ -80,7 +80,7 @@ public async Task ResultOfAsyncShouldProduceExpectedSuccessResult() public async Task ResultOfAsyncShouldProduceExpectedFailureResult() { // Given / When - Result result = await Result.OfAsync(async () => await Task.FromException(FailureException)); + Result result = await Result.OfAsync(async () => await Task.FromException(FailureException), TestContext.Current.CancellationToken); // Then Assert.IsType>(result); @@ -418,7 +418,8 @@ await result.MatchAsync( isSuccess = true; return Task.CompletedTask; }, - failure: _ => isFailure = true + failure: _ => isFailure = true, + token: TestContext.Current.CancellationToken ); // Then @@ -441,7 +442,8 @@ await result.MatchAsync( isSuccess = true; return Task.CompletedTask; }, - failure: _ => isFailure = true + failure: _ => isFailure = true, + token: TestContext.Current.CancellationToken ); // Then @@ -514,7 +516,8 @@ await result.MatchAsync( { isFailure = true; return Task.CompletedTask; - } + }, + token: TestContext.Current.CancellationToken ); // Then @@ -537,7 +540,8 @@ await result.MatchAsync( { isFailure = true; return Task.CompletedTask; - } + }, + token: TestContext.Current.CancellationToken ); // Then @@ -755,7 +759,8 @@ public async Task ResultMatchAsyncFuncTTaskTResultFuncExceptionTResultFromSucces // When int actual = await result.MatchAsync( success: _ => Task.FromResult(1), - failure: _ => 0 + failure: _ => 0, + token: TestContext.Current.CancellationToken ); // Then @@ -772,7 +777,8 @@ public async Task ResultMatchAsyncFuncTTaskTResultFuncExceptionTResultFromFailur // When int actual = await result.MatchAsync( success: _ => Task.FromResult(0), - failure: _ => 1 + failure: _ => 1, + token: TestContext.Current.CancellationToken ); // Then @@ -827,7 +833,8 @@ public async Task ResultMatchAsyncFuncTResultFuncExceptionTaskTResultFromSuccess // When int actual = await result.MatchAsync( success: _ => 1, - failure: _ => Task.FromResult(0) + failure: _ => Task.FromResult(0), + token: TestContext.Current.CancellationToken ); // Then @@ -844,7 +851,8 @@ public async Task ResultMatchAsyncFuncTResultFuncExceptionTaskTResultFromFailure // When int actual = await result.MatchAsync( success: _ => 0, - failure: _ => Task.FromResult(1) + failure: _ => Task.FromResult(1), + token: TestContext.Current.CancellationToken ); // Then @@ -1015,7 +1023,7 @@ public async Task ResultSelectAsyncFuncTTaskFromFailureShouldProduceExpectedResu Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(_ => Task.CompletedTask); + Result actual = await result.SelectAsync(_ => Task.CompletedTask, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1029,7 +1037,7 @@ public async Task ResultSelectAsyncFuncTTaskFromSuccessShouldProduceExpectedResu Result expected = Result.Success(); // When - Result actual = await result.SelectAsync(_ => Task.CompletedTask); + Result actual = await result.SelectAsync(_ => Task.CompletedTask, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1043,7 +1051,7 @@ public async Task ResultSelectAsyncFuncTTaskFromSuccessWithExceptionShouldProduc Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(_ => throw FailureException); + Result actual = await result.SelectAsync(_ => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1144,7 +1152,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromFailureShouldProduceExpe Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(_ => Task.FromResult(1)); + Result actual = await result.SelectAsync(_ => Task.FromResult(1), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1158,7 +1166,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromSuccessShouldProduceExpe Result expected = Result.Success(1); // When - Result actual = await result.SelectAsync(_ => Task.FromResult(1)); + Result actual = await result.SelectAsync(_ => Task.FromResult(1), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1172,7 +1180,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromSuccessWithExceptionShou Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(_ => throw FailureException); + Result actual = await result.SelectAsync(_ => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1273,7 +1281,8 @@ public async Task ResultSelectManyAsyncFunctionFromFailureShouldProduceExpectedR Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(async _ => await Task.FromResult(Result.Success())); + Result actual = await result.SelectManyAsync(async _ => + await Task.FromResult(Result.Success()), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1287,7 +1296,8 @@ public async Task ResultSelectManyAsyncFunctionFromSuccessShouldProduceExpectedR Result expected = Result.Success(); // When - Result actual = await result.SelectManyAsync(async _ => await Task.FromResult(Result.Success())); + Result actual = await result.SelectManyAsync(async _ => + await Task.FromResult(Result.Success()), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1301,7 +1311,7 @@ public async Task ResultSelectManyAsyncFunctionFromSuccessWithExceptionShouldPro Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(_ => throw FailureException); + Result actual = await result.SelectManyAsync(_ => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1402,7 +1412,8 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromFailureShouldProduce Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(async _ => await Task.FromResult(Result.Success(1))); + Result actual = await result.SelectManyAsync(async _ => + await Task.FromResult(Result.Success(1)), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1416,7 +1427,8 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromSuccessShouldProduce Result expected = Result.Success(1); // When - Result actual = await result.SelectManyAsync(async _ => await Task.FromResult(Result.Success(1))); + Result actual = await result.SelectManyAsync(async _ => + await Task.FromResult(Result.Success(1)), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1430,7 +1442,7 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromSuccessWithException Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(_ => throw FailureException); + Result actual = await result.SelectManyAsync(_ => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); diff --git a/OnixLabs.Core.UnitTests/ResultTests.cs b/OnixLabs.Core.UnitTests/ResultTests.cs index a955c2c..02c8ef7 100644 --- a/OnixLabs.Core.UnitTests/ResultTests.cs +++ b/OnixLabs.Core.UnitTests/ResultTests.cs @@ -69,7 +69,7 @@ public void ResultOfShouldProduceExpectedFailureResult() public async Task ResultOfAsyncShouldProduceExpectedSuccessResult() { // Given / When - Result result = await Result.OfAsync(async () => await Task.CompletedTask); + Result result = await Result.OfAsync(async () => await Task.CompletedTask, TestContext.Current.CancellationToken); // Then Assert.IsType(result); @@ -79,7 +79,7 @@ public async Task ResultOfAsyncShouldProduceExpectedSuccessResult() public async Task ResultOfAsyncShouldProduceExpectedFailureResult() { // Given / When - Result result = await Result.OfAsync(async () => await Task.FromException(FailureException)); + Result result = await Result.OfAsync(async () => await Task.FromException(FailureException), TestContext.Current.CancellationToken); // Then Assert.IsType(result); @@ -344,7 +344,7 @@ public async Task ResultMatchAsyncFuncTaskActionFromSuccessShouldProduceExpected bool isFailure = false; // When - await result.MatchAsync(Success, Failure); + await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.True(isSuccess); @@ -370,7 +370,7 @@ public async Task ResultMatchAsyncFuncTaskActionFromFailureShouldProduceExpected bool isFailure = false; // When - await result.MatchAsync(Success, Failure); + await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.False(isSuccess); @@ -450,7 +450,7 @@ public async Task ResultMatchAsyncActionFuncExceptionTaskFromSuccessShouldProduc bool isFailure = false; // When - await result.MatchAsync(Success, Failure); + await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.True(isSuccess); @@ -475,7 +475,7 @@ public async Task ResultMatchAsyncActionFuncExceptionTaskFromFailureShouldProduc bool isFailure = false; // When - await result.MatchAsync(Success, Failure); + await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.False(isSuccess); @@ -711,7 +711,7 @@ public async Task ResultMatchAsyncFuncTaskTResultFuncExceptionTResultFromSuccess const int expected = 1; // When - int actual = await result.MatchAsync(Success, Failure); + int actual = await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -729,7 +729,7 @@ public async Task ResultMatchAsyncFuncTaskTResultFuncExceptionTResultFromFailure const int expected = 0; // When - int actual = await result.MatchAsync(Success, Failure); + int actual = await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -785,7 +785,7 @@ public async Task ResultMatchAsyncFuncTResultFuncExceptionTaskTResultFromSuccess const int expected = 1; // When - int actual = await result.MatchAsync(Success, Failure); + int actual = await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -803,7 +803,7 @@ public async Task ResultMatchAsyncFuncTResultFuncExceptionTaskTResultFromFailure const int expected = 0; // When - int actual = await result.MatchAsync(Success, Failure); + int actual = await result.MatchAsync(Success, Failure, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -977,7 +977,7 @@ public async Task ResultSelectAsyncFuncTaskFromFailureShouldProduceExpectedResul Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(() => Task.CompletedTask); + Result actual = await result.SelectAsync(() => Task.CompletedTask, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -991,7 +991,7 @@ public async Task ResultSelectAsyncFuncTaskFromSuccessShouldProduceExpectedResul Result expected = Result.Success(); // When - Result actual = await result.SelectAsync(() => Task.CompletedTask); + Result actual = await result.SelectAsync(() => Task.CompletedTask, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1005,7 +1005,7 @@ public async Task ResultSelectAsyncFuncTaskFromSuccessWithExceptionShouldProduce Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(() => throw FailureException); + Result actual = await result.SelectAsync(() => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1106,7 +1106,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromFailureShouldProduceExpe Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(() => Task.FromResult(1)); + Result actual = await result.SelectAsync(() => Task.FromResult(1), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1120,7 +1120,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromSuccessShouldProduceExpe Result expected = 1; // When - Result actual = await result.SelectAsync(() => Task.FromResult(1)); + Result actual = await result.SelectAsync(() => Task.FromResult(1), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1134,7 +1134,7 @@ public async Task ResultSelectAsyncFunctionOfTResultFromSuccessWithExceptionShou Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectAsync(() => throw FailureException); + Result actual = await result.SelectAsync(() => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1235,7 +1235,7 @@ public async Task ResultSelectManyAsyncFunctionFromFailureShouldProduceExpectedR Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success())); + Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success()), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1249,7 +1249,7 @@ public async Task ResultSelectManyAsyncFunctionFromSuccessShouldProduceExpectedR Result expected = Result.Success(); // When - Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success())); + Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success()), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1263,7 +1263,7 @@ public async Task ResultSelectManyAsyncFunctionFromSuccessWithExceptionShouldPro Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(() => throw FailureException); + Result actual = await result.SelectManyAsync(() => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1364,7 +1364,8 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromFailureShouldProduce Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success(1))); + Result actual = await result.SelectManyAsync(async () => + await Task.FromResult(Result.Success(1)), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1378,7 +1379,8 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromSuccessShouldProduce Result expected = Result.Success(1); // When - Result actual = await result.SelectManyAsync(async () => await Task.FromResult(Result.Success(1))); + Result actual = await result.SelectManyAsync(async () => + await Task.FromResult(Result.Success(1)), TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); @@ -1392,7 +1394,7 @@ public async Task ResultSelectManyAsyncFunctionOfTResultFromSuccessWithException Result expected = Result.Failure(FailureException); // When - Result actual = await result.SelectManyAsync(() => throw FailureException); + Result actual = await result.SelectManyAsync(() => throw FailureException, TestContext.Current.CancellationToken); // Then Assert.Equal(expected, actual); diff --git a/OnixLabs.Core/Collections/Collection.Empty.cs b/OnixLabs.Core/Collections/Collection.Empty.cs index 53c8fce..31ee7b0 100644 --- a/OnixLabs.Core/Collections/Collection.Empty.cs +++ b/OnixLabs.Core/Collections/Collection.Empty.cs @@ -23,42 +23,42 @@ namespace OnixLabs.Core.Collections; public static partial class Collection { /// - /// Creates an empty enumerable. + /// Creates an empty . /// /// The underlying type of the enumerable. /// Returns an empty enumerable. public static IEnumerable EmptyEnumerable() => []; /// - /// Creates an empty array. + /// Creates an empty array. /// /// The underlying type of the array. /// Returns an empty array. public static T[] EmptyArray() => []; /// - /// Creates an empty immutable array. + /// Creates an empty . /// /// The underlying type of the immutable array. /// Returns an empty immutable array. public static ImmutableArray EmptyImmutableArray() => []; /// - /// Creates an empty list. + /// Creates an empty . /// /// The underlying type of the list. /// Returns an empty list. public static List EmptyList() => []; /// - /// Creates an empty immutable list. + /// Creates an empty . /// /// The underlying type of the immutable list. /// Returns an empty immutable list. public static ImmutableList EmptyImmutableList() => []; /// - /// Creates an empty dictionary. + /// Creates an empty . /// /// The underlying type of the dictionary key. /// The underlying type of the dictionary value. @@ -66,7 +66,7 @@ public static partial class Collection public static Dictionary EmptyDictionary() where TKey : notnull => []; /// - /// Creates an empty immutable dictionary. + /// Creates an empty . /// /// The underlying type of the immutable dictionary key. /// The underlying type of the immutable dictionary value. @@ -74,7 +74,7 @@ public static partial class Collection public static ImmutableDictionary EmptyImmutableDictionary() where TKey : notnull => ImmutableDictionary.Empty; /// - /// Creates an empty sorted dictionary. + /// Creates an empty . /// /// The underlying type of the sorted dictionary key. /// The underlying type of the sorted dictionary value. @@ -82,7 +82,7 @@ public static partial class Collection public static SortedDictionary EmptySortedDictionary() where TKey : notnull => []; /// - /// Creates an empty immutable sorted dictionary. + /// Creates an empty . /// /// The underlying type of the immutable sorted dictionary key. /// The underlying type of the immutable sorted dictionary value. @@ -90,56 +90,56 @@ public static partial class Collection public static ImmutableSortedDictionary EmptyImmutableSortedDictionary() where TKey : notnull => ImmutableSortedDictionary.Empty; /// - /// Creates an empty hash set. + /// Creates an empty . /// /// The underlying type of the hash set. /// Returns an empty hash set. public static HashSet EmptyHashSet() => []; /// - /// Creates an empty immutable hash set. + /// Creates an empty . /// /// The underlying type of the immutable hash set. /// Returns an empty immutable hash set. public static ImmutableHashSet EmptyImmutableHashSet() => []; /// - /// Creates an empty sorted set. + /// Creates an empty . /// /// The underlying type of the sorted set. /// Returns an empty sorted set. public static SortedSet EmptySortedSet() => []; /// - /// Creates an empty immutable sorted set. + /// Creates an empty . /// /// The underlying type of the immutable sorted set. /// Returns an empty immutable sorted set. public static ImmutableSortedSet EmptyImmutableSortedSet() => []; /// - /// Creates an empty stack. + /// Creates an empty . /// /// The underlying type of the stack. /// Returns an empty stack. public static Stack EmptyStack() => []; /// - /// Creates an empty immutable stack. + /// Creates an empty . /// /// The underlying type of the immutable stack. /// Returns an empty immutable stack. public static ImmutableStack EmptyImmutableStack() => []; /// - /// Creates an empty queue. + /// Creates an empty . /// /// The underlying type of the queue. /// Returns an empty queue. public static Queue EmptyQueue() => []; /// - /// Creates an empty immutable queue. + /// Creates an empty . /// /// The underlying type of the immutable queue. /// Returns an empty immutable queue. diff --git a/OnixLabs.Core/Collections/Collection.Of.cs b/OnixLabs.Core/Collections/Collection.Of.cs index c24d077..a6b7ec9 100644 --- a/OnixLabs.Core/Collections/Collection.Of.cs +++ b/OnixLabs.Core/Collections/Collection.Of.cs @@ -18,10 +18,11 @@ namespace OnixLabs.Core.Collections; +// ReSharper disable MemberCanBePrivate.Global public static partial class Collection { /// - /// Creates an enumerable of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the enumerable. /// The underlying type of the enumerable. @@ -29,7 +30,7 @@ public static partial class Collection public static IEnumerable EnumerableOf(params IEnumerable items) => items; /// - /// Creates an array of the specified items. + /// Creates a array of the specified items. /// /// The items which will populate the array. /// The underlying type of the array. @@ -37,7 +38,7 @@ public static partial class Collection public static T[] ArrayOf(params T[] items) => items; /// - /// Creates an immutable array of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable array. /// The underlying type of the immutable array. @@ -45,7 +46,7 @@ public static partial class Collection public static ImmutableArray ImmutableArrayOf(params ImmutableArray items) => items; /// - /// Creates a list of the specified items. + /// Creates a of the specified items. /// /// The items which will populate the list. /// The underlying type of the list. @@ -53,7 +54,7 @@ public static partial class Collection public static List ListOf(params List items) => items; /// - /// Creates an immutable list of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable list. /// The underlying type of the immutable list. @@ -61,7 +62,7 @@ public static partial class Collection public static ImmutableList ImmutableListOf(params ImmutableList items) => items; /// - /// Creates a hash set of the specified items. + /// Creates a of the specified items. /// /// The items which will populate the hash set. /// The underlying type of the hash set. @@ -69,7 +70,7 @@ public static partial class Collection public static HashSet HashSetOf(params HashSet items) => items; /// - /// Creates an immutable hash set of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable hash set. /// The underlying type of the immutable hash set. @@ -77,7 +78,7 @@ public static partial class Collection public static ImmutableHashSet ImmutableHashSetOf(params ImmutableHashSet items) => items; /// - /// Creates a sorted set of the specified items. + /// Creates a of the specified items. /// /// The items which will populate the sorted set. /// The underlying type of the sorted set. @@ -85,7 +86,7 @@ public static partial class Collection public static SortedSet SortedSetOf(params SortedSet items) => items; /// - /// Creates an immutable sorted set of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable sorted set. /// The underlying type of the immutable sorted set. @@ -93,7 +94,7 @@ public static partial class Collection public static ImmutableSortedSet ImmutableSortedSetOf(params ImmutableSortedSet items) => items; /// - /// Creates a stack of the specified items. + /// Creates a of the specified items. /// /// The items which will populate the stack. /// The underlying type of the stack. @@ -101,7 +102,7 @@ public static partial class Collection public static Stack StackOf(params IEnumerable items) => new(items); /// - /// Creates an immutable stack of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable stack. /// The underlying type of the immutable stack. @@ -109,7 +110,7 @@ public static partial class Collection public static ImmutableStack ImmutableStackOf(params ImmutableStack items) => items; /// - /// Creates a queue of the specified items. + /// Creates a of the specified items. /// /// The items which will populate the queue. /// The underlying type of the queue. @@ -117,7 +118,7 @@ public static partial class Collection public static Queue QueueOf(params IEnumerable items) => new(items); /// - /// Creates an immutable queue of the specified items. + /// Creates an of the specified items. /// /// The items which will populate the immutable queue. /// The underlying type of the immutable queue. @@ -125,7 +126,7 @@ public static partial class Collection public static ImmutableQueue ImmutableQueueOf(params ImmutableQueue items) => items; /// - /// Create a dictionary of the specified items. + /// Create a of the specified items. /// /// The items which wil populate the dictionary. /// The underlying type of the dictionary key. @@ -135,7 +136,7 @@ public static Dictionary DictionaryOf (params IEnumerable> items) where TKey : notnull => new(items); /// - /// Create a dictionary of the specified items. + /// Create a of the specified items. /// /// The items which wil populate the dictionary. /// The underlying type of the dictionary key. @@ -146,7 +147,7 @@ public static Dictionary DictionaryOf DictionaryOf(items.Select(item => new KeyValuePair(item.key, item.value))); /// - /// Create an immutable dictionary of the specified items. + /// Create an of the specified items. /// /// The items which wil populate the immutable dictionary. /// The underlying type of the immutable dictionary key. @@ -156,7 +157,7 @@ public static ImmutableDictionary ImmutableDictionaryOf> items) where TKey : notnull => ImmutableDictionary.CreateRange(items); /// - /// Create an immutable dictionary of the specified items. + /// Create an of the specified items. /// /// The items which wil populate the immutable dictionary. /// The underlying type of the immutable dictionary key. @@ -167,7 +168,7 @@ public static ImmutableDictionary ImmutableDictionaryOf new KeyValuePair(item.key, item.value))); /// - /// Create a sorted dictionary of the specified items. + /// Create a of the specified items. /// /// The items which wil populate the sorted dictionary. /// The underlying type of the sorted dictionary key. @@ -177,7 +178,7 @@ public static SortedDictionary SortedDictionaryOf (params IEnumerable> items) where TKey : notnull => new(DictionaryOf(items)); /// - /// Create a sorted dictionary of the specified items. + /// Create a of the specified items. /// /// The items which wil populate the sorted dictionary. /// The underlying type of the sorted dictionary key. @@ -187,7 +188,7 @@ public static SortedDictionary SortedDictionaryOf (params IEnumerable<(TKey key, TValue value)> items) where TKey : notnull => new(DictionaryOf(items)); /// - /// Create an immutable sorted dictionary of the specified items. + /// Create an of the specified items. /// /// The items which wil populate the immutable sorted dictionary. /// The underlying type of the immutable sorted dictionary key. @@ -197,7 +198,7 @@ public static ImmutableSortedDictionary ImmutableSortedDictionaryO (params IEnumerable> items) where TKey : notnull => ImmutableSortedDictionary.CreateRange(items); /// - /// Create an immutable sorted dictionary of the specified items. + /// Create an of the specified items. /// /// The items which wil populate the immutable sorted dictionary. /// The underlying type of the immutable sorted dictionary key. diff --git a/OnixLabs.Core/Collections/Generic/Extensions.IEqualityComparer.cs b/OnixLabs.Core/Collections/Generic/Extensions.IEqualityComparer.cs index 7e57701..ee1ea6d 100644 --- a/OnixLabs.Core/Collections/Generic/Extensions.IEqualityComparer.cs +++ b/OnixLabs.Core/Collections/Generic/Extensions.IEqualityComparer.cs @@ -18,17 +18,23 @@ namespace OnixLabs.Core.Collections.Generic; /// -/// Provides LINQ-like extension methods for . +/// Provides extension methods for instances. /// // ReSharper disable InconsistentNaming [EditorBrowsable(EditorBrowsableState.Never)] public static class IEqualityComparerExtensions { /// - /// Gets the current , or the default comparer if the current comparer is . + /// Provides extension methods for instances. /// - /// The current . - /// The underlying type of the current . - /// Returns the current , or the default comparer if the current comparer is . - public static IEqualityComparer GetOrDefault(this IEqualityComparer? comparer) => comparer ?? EqualityComparer.Default; + /// The current instance. + /// The underlying type of the current instance. + extension(IEqualityComparer? receiver) + { + /// + /// Gets the current , or the default comparer if the current comparer is . + /// + /// Returns the current , or the default comparer if the current comparer is . + public IEqualityComparer GetOrDefault() => receiver ?? EqualityComparer.Default; + } } diff --git a/OnixLabs.Core/Enumeration.Get.cs b/OnixLabs.Core/Enumeration.Get.cs index 56d84f7..5aa0568 100644 --- a/OnixLabs.Core/Enumeration.Get.cs +++ b/OnixLabs.Core/Enumeration.Get.cs @@ -22,9 +22,9 @@ namespace OnixLabs.Core; public abstract partial class Enumeration { /// - /// Gets all of the enumeration entries for the current type. + /// Gets all the enumeration entries for the current type. /// - /// Returns all of the enumeration entries for the current type. + /// Returns all the enumeration entries for the current type. public static IReadOnlySet GetAll() => typeof(T) .GetFields(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly) .Select(field => field.GetValue(null)) @@ -32,20 +32,20 @@ public static IReadOnlySet GetAll() => typeof(T) .ToFrozenSet(); /// - /// Gets all of the enumeration entries for the current type. + /// Gets all the enumeration entries for the current type. /// - /// Returns all of the enumeration entries for the current type. + /// Returns all the enumeration entries for the current type. public static IReadOnlySet<(int Value, string Name)> GetEntries() => GetAll().Select(entry => entry.ToEntry()).ToFrozenSet(); /// - /// Gets all of the enumeration names for the current type. + /// Gets all the enumeration names for the current type. /// - /// Returns all of the enumeration names for the current type. + /// Returns all the enumeration names for the current type. public static IReadOnlySet GetNames() => GetAll().Select(entry => entry.Name).ToFrozenSet(); /// - /// Gets all of the enumeration values for the current type. + /// Gets all the enumeration values for the current type. /// - /// Returns all of the enumeration values for the current type. + /// Returns all the enumeration values for the current type. public static IReadOnlySet GetValues() => GetAll().Select(entry => entry.Value).ToFrozenSet(); } diff --git a/OnixLabs.Core/Extensions.Array.cs b/OnixLabs.Core/Extensions.Array.cs index 39b0651..9b5c60c 100644 --- a/OnixLabs.Core/Extensions.Array.cs +++ b/OnixLabs.Core/Extensions.Array.cs @@ -25,37 +25,45 @@ namespace OnixLabs.Core; public static class ArrayExtensions { /// - /// Creates a copy of the current . + /// Provides extensions for generic arrays. /// - /// The current to copy. - /// The underlying type of the array. - /// Returns an exact copy of the current . - public static T[] Copy(this T[] array) => [..array]; + /// The current generic array. + /// The underlying element type of the current generic array. + extension(T[] receiver) + { + /// + /// Creates a copy of the current array. + /// + /// Returns an exact copy of the current array. + public T[] Copy() => [..receiver]; - /// - /// Creates a copy of the current . - /// - /// The current to copy. - /// The index of the array to begin copying from. - /// The number of elements of the array to copy. - /// The underlying type of the array. - /// Returns an exact copy of the current . - public static T[] Copy(this T[] array, int index, int count) => [..array[index..(index + count)]]; + /// + /// Creates a copy of the current array. + /// + /// The index of the array to begin copying from. + /// The number of elements of the array to copy. + /// Returns an exact copy of the current array. + public T[] Copy(int index, int count) => [..receiver[index..(index + count)]]; - /// - /// Concatenates the current with another . - /// - /// The source to concatenate with the other . - /// The other to concatenate with the source . - /// The underlying type of the . - /// Returns the current concatenated with the other . - public static T[] ConcatenateWith(this T[] array, T[] other) => [..array, ..other]; + /// + /// Concatenates the current array with another array. + /// + /// The other array to concatenate with the current array. + /// Returns a new array, consisting of the current array concatenated with the other array. + public T[] ConcatenateWith(T[] other) => [..receiver, ..other]; + } /// - /// Obtains the representation of the current . + /// Provides extension methods for arrays. /// - /// The instance from which to obtain a representation. - /// The which will be used to convert the current into a representation. - /// Returns the representation of the current . - public static string ToString(this byte[] array, Encoding encoding) => encoding.GetString(array); + /// The current array. + extension(byte[] receiver) + { + /// + /// Obtains the representation of the current array. + /// + /// The which will be used to convert the current array into a representation. + /// Returns the representation of the current array. + public string ToString(Encoding encoding) => encoding.GetString(receiver); + } } diff --git a/OnixLabs.Core/Extensions.DateTime.cs b/OnixLabs.Core/Extensions.DateTime.cs index 1380886..76498bc 100644 --- a/OnixLabs.Core/Extensions.DateTime.cs +++ b/OnixLabs.Core/Extensions.DateTime.cs @@ -24,16 +24,21 @@ namespace OnixLabs.Core; public static class DateTimeExtensions { /// - /// Obtains a instance from the current instance. + /// Provides extension methods for instances. /// - /// The instance from which to obtain a instance. - /// Returns the instance obtained from the current instance. - public static DateOnly ToDateOnly(this DateTime value) => DateOnly.FromDateTime(value); + /// The current instance. + extension(DateTime receiver) + { + /// + /// Obtains a instance from the current instance. + /// + /// Returns the instance obtained from the current instance. + public DateOnly ToDateOnly() => DateOnly.FromDateTime(receiver); - /// - /// Obtains a instance from the current instance. - /// - /// The instance from which to obtain a instance. - /// Returns the instance obtained from the current instance. - public static TimeOnly ToTimeOnly(this DateTime value) => TimeOnly.FromDateTime(value); + /// + /// Obtains a instance from the current instance. + /// + /// Returns the instance obtained from the current instance. + public TimeOnly ToTimeOnly() => TimeOnly.FromDateTime(receiver); + } } diff --git a/OnixLabs.Core/Extensions.Object.cs b/OnixLabs.Core/Extensions.Object.cs index bd8e297..0329f34 100644 --- a/OnixLabs.Core/Extensions.Object.cs +++ b/OnixLabs.Core/Extensions.Object.cs @@ -49,7 +49,7 @@ public static class ObjectExtensions /// Returns the current once the specified has been executed. public static T Apply(this T value, Action action) where T : class { - RequireNotNull(action, "Action must not be null.", nameof(action)); + RequireNotNull(action, "Action must not be null."); action(value); return value; } @@ -63,7 +63,7 @@ public static T Apply(this T value, Action action) where T : class /// Returns the result of the specified . public static T Apply(this T value, Func function) where T : struct { - RequireNotNull(function, "Function must not be null.", nameof(function)); + RequireNotNull(function, "Function must not be null."); return function(value); } @@ -145,7 +145,7 @@ public static bool IsWithinRangeExclusive(this T value, T min, T max) where T /// Returns the result of the specified . public static TResult Let(this TSource value, Func function) { - RequireNotNull(function, "Function must not be null.", nameof(function)); + RequireNotNull(function, "Function must not be null."); return function(value); } diff --git a/OnixLabs.Core/Extensions.Random.cs b/OnixLabs.Core/Extensions.Random.cs index e761df1..7a84ec8 100644 --- a/OnixLabs.Core/Extensions.Random.cs +++ b/OnixLabs.Core/Extensions.Random.cs @@ -25,11 +25,17 @@ namespace OnixLabs.Core; public static class RandomExtensions { /// - /// Obtains a random element from the specified items. + /// Provides extension methods for instances. /// - /// The current instance. - /// The items from which to obtain a random element. - /// The underlying type of the collection. - /// Returns a random element from the specified items. - public static T Next(this Random random, IReadOnlyList items) => items[random.Next(0, items.Count)]; + /// The current instance. + extension(Random receiver) + { + /// + /// Obtains a random element from the specified items. + /// + /// The items from which to obtain a random element. + /// The underlying type of the collection. + /// Returns a random element from the specified items. + public T Next(IReadOnlyList items) => items[receiver.Next(0, items.Count)]; + } } diff --git a/OnixLabs.Core/Extensions.ReadOnlySequence.cs b/OnixLabs.Core/Extensions.ReadOnlySequence.cs index e82a6ef..d26fb9d 100644 --- a/OnixLabs.Core/Extensions.ReadOnlySequence.cs +++ b/OnixLabs.Core/Extensions.ReadOnlySequence.cs @@ -24,22 +24,26 @@ namespace OnixLabs.Core; public static class ReadOnlySequenceExtensions { /// - /// Copies the current to the specified by reference. + /// Provides extension methods for instances. /// - /// The current to copy. - /// The to copy to. - /// The underlying type of the specified and . - public static void CopyTo(this ReadOnlySequence sequence, out T[] array) + /// The current instance. + /// The underlying type of the current instance. + extension(ReadOnlySequence receiver) { - if (sequence.IsSingleSegment) + /// + /// Copies the current to the specified array. + /// + /// The array to copy in to. + public void CopyTo(out T[] array) { - array = sequence.First.Span.ToArray(); - } - else - { - // ReSharper disable once HeapView.ObjectAllocation.Evident - array = new T[sequence.Length]; - sequence.CopyTo(array); + if (receiver.IsSingleSegment) + array = receiver.First.Span.ToArray(); + else + { + // ReSharper disable once HeapView.ObjectAllocation.Evident + array = new T[receiver.Length]; + receiver.CopyTo(array); + } } } } diff --git a/OnixLabs.Core/Extensions.Result.cs b/OnixLabs.Core/Extensions.Result.cs index 3ab6909..3fd1adf 100644 --- a/OnixLabs.Core/Extensions.Result.cs +++ b/OnixLabs.Core/Extensions.Result.cs @@ -20,133 +20,746 @@ namespace OnixLabs.Core; /// -/// Provides extension methods for instances. +/// Provides extension methods for and instances. /// [EditorBrowsable(EditorBrowsableState.Never)] public static class ResultExtensions { /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or if the current is in a state. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or if the current is in a state. - /// - public static async Task GetExceptionOrDefaultAsync(this Task task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(); - - /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or the specified default exception if the current is in a state. - /// - /// The current of . - /// The default exception to return in the event that the current is in a state. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or the specified default exception if the current is in a state. - /// - public static async Task GetExceptionOrDefaultAsync(this Task task, Exception defaultException, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(defaultException); - - /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or throws if the current is in a state. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or throws if the current is in a state. - /// - public static async Task GetExceptionOrThrowAsync(this Task task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrThrow(); - - /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or if the current is in a state. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or if the current is in a state. - /// - public static async Task GetExceptionOrDefaultAsync(this Task> task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(); - - /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or the specified default exception if the current is in a state. - /// - /// The current of . - /// The default exception to return in the event that the current is in a state. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or the specified default exception if the current is in a state. - /// - public static async Task GetExceptionOrDefaultAsync(this Task> task, Exception defaultException, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(defaultException); - - /// - /// Asynchronously gets the underlying exception if the current is in a state, - /// or throws if the current is in a state. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns the underlying exception if the current is in a state, - /// or throws if the current is in a state. - /// - public static async Task GetExceptionOrThrowAsync(this Task> task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrThrow(); - - /// - /// Asynchronously gets the underlying value of the current instance, if the underlying value is present; - /// otherwise returns the default value. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the value. - /// - /// Returns the underlying value of the current instance, if the underlying value is present; - /// otherwise returns the default value. - /// - public static async Task GetValueOrDefaultAsync(this Task> task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetValueOrDefault(); - - /// - /// Asynchronously gets the underlying value of the current instance, if the underlying value is present; - /// otherwise returns the specified default value. - /// - /// The current of . - /// The default value to return in the event that the underlying value is absent. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the value. - /// - /// Returns the underlying value of the current instance, if the underlying value is present; - /// otherwise returns the specified default value. - /// - public static async Task GetValueOrDefaultAsync(this Task> task, T defaultValue, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetValueOrDefault(defaultValue); - - /// - /// Asynchronously gets the underlying value of the current instance; - /// otherwise throws the underlying exception if the current is in a failed stated. - /// - /// The current of . - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the value. - /// - /// Returns the underlying value of the current instance; - /// otherwise throws the underlying exception if the current is in a failed stated. - /// - public static async Task GetValueOrThrowAsync(this Task> task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).GetValueOrThrow(); + /// Provides extension methods for of instances. + /// + /// The current of instance. + extension(Task receiver) + { + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or if the current is in a state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or if the current is in a state. + /// + public async Task GetExceptionOrDefaultAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(); + + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or the specified default exception if the current is in a state. + /// + /// The default exception to return in the event that the current is in a state. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or the specified default exception if the current is in a state. + /// + public async Task GetExceptionOrDefaultAsync(Exception defaultException, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(defaultException); + + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or throws if the current is in a state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or throws if the current is in a state. + /// + public async Task GetExceptionOrThrowAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrThrow(); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Action? failure = null, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Action? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Action? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func failure, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Action selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Select(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Func selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Func selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Select(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func> selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func>> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func>> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously throws the underlying exception if the current is in a failure state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + public async Task ThrowAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Throw(); + } + + /// + /// Provides extension methods for of instances. + /// + /// The current of instance. + extension(Task> receiver) + { + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or if the current is in a state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or if the current is in a state. + /// + public async Task GetExceptionOrDefaultAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(); + + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or the specified default exception if the current is in a state. + /// + /// The default exception to return in the event that the current is in a state. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or the specified default exception if the current is in a state. + /// + public async Task GetExceptionOrDefaultAsync(Exception defaultException, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrDefault(defaultException); + + /// + /// Asynchronously gets the underlying exception if the current is in a state, + /// or throws if the current is in a state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying exception if the current is in a state, + /// or throws if the current is in a state. + /// + public async Task GetExceptionOrThrowAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetExceptionOrThrow(); + + /// + /// Asynchronously gets the underlying value of the current instance, if the underlying value is present; + /// otherwise returns the default value. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying value of the current instance, if the underlying value is present; + /// otherwise returns the default value. + /// + public async Task GetValueOrDefaultAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetValueOrDefault(); + + /// + /// Asynchronously gets the underlying value of the current instance, if the underlying value is present; + /// otherwise returns the specified default value. + /// + /// The default value to return in the event that the underlying value is absent. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying value of the current instance, if the underlying value is present; + /// otherwise returns the specified default value. + /// + public async Task GetValueOrDefaultAsync(T defaultValue, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetValueOrDefault(defaultValue); + + /// + /// Asynchronously gets the underlying value of the current instance; + /// otherwise throws the underlying exception if the current is in a failed stated. + /// + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns the underlying value of the current instance; + /// otherwise throws the underlying exception if the current is in a failed stated. + /// + public async Task GetValueOrThrowAsync(CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).GetValueOrThrow(); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Action? failure = null, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Action? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Action? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Action? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + public async Task MatchAsync(Func? success = null, Func? failure = null, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func failure, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. + /// + /// The delegate to execute when the current instance is in a successful state. + /// The delegate to execute when the current instance is in a failed state. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the matching delegate. + /// + /// Returns the result of the delegate if the current instance is in a successful state; + /// otherwise, returns the result of the delegate if the current instance is in a failed state. + /// + public async Task MatchAsync(Func> success, Func> failure, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Action selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Select(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Func selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectAsync(Func selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).Select(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task SelectManyAsync(Func> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func> selector, CancellationToken token = default) => + (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func>> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously applies the provided selector delegate to the value of the current instance. + /// + /// The delegate to apply to the value of the current instance. + /// The cancellation token that can be used to cancel long-running tasks. + /// The underlying type of the result produced by the selector delegate. + /// + /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . + /// + public async Task> SelectManyAsync(Func>> selector, CancellationToken token = default) => + await (await receiver.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); + + /// + /// Asynchronously throws the underlying exception if the current is in a failure state. + /// + /// The cancellation token that can be used to cancel long-running tasks. + public async Task ThrowAsync(CancellationToken token = default) => (await receiver.WaitAsync(token).ConfigureAwait(false)).Throw(); + } /// /// Gets the value of the current instance, @@ -258,696 +871,6 @@ public static T GetOptionalValueOrDefault(this Result> result, T public static async Task GetOptionalValueOrDefaultAsync(this Task>> task, T defaultValue, CancellationToken token = default) where T : notnull => (await task.WaitAsync(token).ConfigureAwait(false)).GetOptionalValueOrDefault(defaultValue); - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Action? success = null, Action? failure = null, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Func? success = null, Action? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Func? success = null, Action? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Action? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Action? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Func? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task MatchAsync(this Task task, Func? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func success, Func failure, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func> success, Func failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func> success, Func failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func> success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task task, Func> success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Action? success = null, Action? failure = null, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Func? success = null, Action? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Func? success = null, Action? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Action? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Action? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Func? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - public static async Task MatchAsync(this Task> task, Func? success = null, Func? failure = null, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func success, Func failure, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Match(success, failure); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func> success, Func failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func> success, Func failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func> success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously executes the delegate that matches the value of the current instance and returns its result. - /// - /// The current of from which to execute the matching delegate. - /// The delegate to execute when the current instance is in a successful state. - /// The delegate to execute when the current instance is in a failed state. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the matching delegate. - /// - /// Returns the result of the delegate if the current instance is in a successful state; - /// otherwise, returns the result of the delegate if the current instance is in a failed state. - /// - public static async Task MatchAsync(this Task> task, Func> success, Func> failure, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).MatchAsync(success, failure, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task task, Action selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Select(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task task, Func selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task task, Func selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task task, Func selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Select(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task> task, Action selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Select(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task> task, Func selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectAsync(this Task> task, Func selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task> task, Func selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Select(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task> task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectAsync(this Task> task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task task, Func selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task task, Func> selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task task, Func>> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task task, Func>> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task> task, Func selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task> task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task SelectManyAsync(this Task> task, Func> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task> task, Func> selector, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).SelectMany(selector); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task> task, Func>> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously applies the provided selector delegate to the value of the current instance. - /// - /// The current of upon which to apply the selector delegate. - /// The delegate to apply to the value of the current instance. - /// The cancellation token that can be used to cancel long-running tasks. - /// The underlying type of the . - /// The underlying type of the result produced by the selector delegate. - /// - /// Returns if the current is in a successful state, and the delegate invocation is also successful; otherwise; . - /// - public static async Task> SelectManyAsync(this Task> task, Func>> selector, CancellationToken token = default) => - await (await task.WaitAsync(token).ConfigureAwait(false)).SelectManyAsync(selector, token).WaitAsync(token).ConfigureAwait(false); - - /// - /// Asynchronously throws the underlying exception if the current is in a failure state. - /// - /// The current of from which to throw the underlying exception. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task ThrowAsync(this Task task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Throw(); - - /// - /// Asynchronously throws the underlying exception if the current is in a failure state. - /// - /// The underlying type of the . - /// The current of from which to throw the underlying exception. - /// The cancellation token that can be used to cancel long-running tasks. - public static async Task ThrowAsync(this Task> task, CancellationToken token = default) => - (await task.WaitAsync(token).ConfigureAwait(false)).Throw(); - /// /// Asynchronously obtains a new instance containing the current exception. /// diff --git a/OnixLabs.Core/Extensions.String.cs b/OnixLabs.Core/Extensions.String.cs index adccb0b..63a2300 100644 --- a/OnixLabs.Core/Extensions.String.cs +++ b/OnixLabs.Core/Extensions.String.cs @@ -43,465 +43,449 @@ public static class StringExtensions private const DateTimeStyles DefaultStyles = DateTimeStyles.None; /// - /// Obtains the zero-based index of the nth occurrence of the specified character in this instance. - /// If the specified occurrence does not exist, returns -1. + /// Provides extension methods for instances. /// - /// The string to search. - /// The character to seek. - /// The number of occurrences to skip before returning an index. - /// - /// Returns the zero-based index position of the nth occurrence of , if found; otherwise, -1. - /// - public static int NthIndexOf(this string value, char seekValue, int count) + /// The current instance. + extension(string receiver) { - if (string.IsNullOrEmpty(value) || count <= 0) return -1; - - int occurrences = 0; - - for (int i = 0; i < value.Length; i++) + /// + /// Obtains the zero-based index of the nth occurrence of the specified character in this instance. + /// If the specified occurrence does not exist, returns -1. + /// + /// The character to seek. + /// The number of occurrences to skip before returning an index. + /// + /// Returns the zero-based index position of the nth occurrence of , if found; otherwise, -1. + /// + public int NthIndexOf(char seekValue, int count) { - if (value[i] != seekValue) continue; - - occurrences++; - - if (occurrences != count) continue; + if (string.IsNullOrEmpty(receiver) || count <= 0) return -1; - return i; - } - - return NotFound; - } + int occurrences = 0; - /// - /// Obtains the zero-based index of the nth occurrence of the specified character in this instance. - /// If the specified occurrence does not exist, returns -1. - /// - /// The string to search. - /// The substring to seek. - /// The number of occurrences to skip before returning an index. - /// The comparison that will be used to compare the current value and the seek value. - /// - /// Returns the zero-based index position of the nth occurrence of , if found; otherwise, -1. - /// - public static int NthIndexOf(this string value, string seekValue, int count, StringComparison comparison = DefaultComparison) - { - if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(seekValue) || count <= 0) return -1; - - int occurrences = 0; - int startIndex = 0; - - while (true) - { - int index = value.IndexOf(seekValue, startIndex, comparison); - - if (index == -1) return -1; + for (int index = 0; index < receiver.Length; index++) + { + if (receiver[index] != seekValue) + continue; - occurrences++; + occurrences++; - if (occurrences == count) return index; + if (occurrences != count) + continue; - startIndex = index + seekValue.Length; + return index; + } - if (startIndex >= value.Length) return NotFound; + return NotFound; } - } - - /// - /// Repeats the current by the specified number of repetitions. - /// - /// The instance to repeat. - /// The number of repetitions of the current instance. - /// Returns a new instance representing the repetition of the current instance. - public static string Repeat(this string value, int count) => - count > 0 ? string.Join(string.Empty, Enumerable.Repeat(value, count)) : string.Empty; - - /// - /// Obtains a sub-string before the specified index within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The index in the current from which to obtain a sub-string. - /// - /// The value to return in the event that the index is less than zero. - /// If the default value is then the current instance is returned. - /// - /// - /// Returns a sub-string before the specified index. If the index is less than zero, then the default value will be returned. - /// If the default value is , then the current instance will be returned. - /// - // ReSharper disable once HeapView.ObjectAllocation - private static string SubstringBeforeIndex(this string value, int index, string? defaultValue = null) => - index <= NotFound ? defaultValue ?? value : value[..index]; - - /// - /// Obtains a sub-string after the specified index within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The index in the current from which to obtain a sub-string. - /// The offset from the index which marks the beginning of the sub-string. - /// - /// The value to return in the event that the index is less than zero. - /// If the default value is then the current instance is returned. - /// - /// - /// Returns a sub-string after the specified index. If the index is less than zero, then the default value will be returned. - /// If the default value is , then the current instance will be returned. - /// - // ReSharper disable once HeapView.ObjectAllocation - private static string SubstringAfterIndex(this string value, int index, int offset, string? defaultValue = null) => - index <= NotFound ? defaultValue ?? value : value[(index + offset)..value.Length]; - - /// - /// Obtains a sub-string before the first occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// Returns a sub-string before the first occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringBeforeFirst(this string value, char delimiter, string? defaultValue = null) => - value.SubstringBeforeIndex(value.IndexOf(delimiter), defaultValue); - - /// - /// Obtains a sub-string before the first occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// The culture, case and sort rules that will be applied when searching for the specified delimiter. - /// The default value is . - /// - /// - ///Returns a sub-string before the first occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringBeforeFirst(this string value, string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => - value.SubstringBeforeIndex(value.IndexOf(delimiter, comparison), defaultValue); - - /// - /// Obtains a sub-string before the last occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - ///Returns a sub-string before the last occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringBeforeLast(this string value, char delimiter, string? defaultValue = null) => - value.SubstringBeforeIndex(value.LastIndexOf(delimiter), defaultValue); - - /// - /// Obtains a sub-string before the last occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// The culture, case and sort rules that will be applied when searching for the specified delimiter. - /// The default value is . - /// - /// - ///Returns a sub-string before the last occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringBeforeLast(this string value, string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => - value.SubstringBeforeIndex(value.LastIndexOf(delimiter, comparison), defaultValue); - /// - /// Obtains a sub-string after the first occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// Returns a sub-string after the first occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringAfterFirst(this string value, char delimiter, string? defaultValue = null) => - value.SubstringAfterIndex(value.IndexOf(delimiter), 1, defaultValue); - - /// - /// Obtains a sub-string after the first occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// The culture, case and sort rules that will be applied when searching for the specified delimiter. - /// The default value is . - /// - /// - ///Returns a sub-string after the first occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringAfterFirst(this string value, string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => - value.SubstringAfterIndex(value.IndexOf(delimiter, comparison), delimiter.Length, defaultValue); + /// + /// Obtains the zero-based index of the nth occurrence of the specified character in this instance. + /// If the specified occurrence does not exist, returns -1. + /// + /// The substring to seek. + /// The number of occurrences to skip before returning an index. + /// The comparison that will be used to compare the current value and the seek value. + /// + /// Returns the zero-based index position of the nth occurrence of , if found; otherwise, -1. + /// + public int NthIndexOf(string seekValue, int count, StringComparison comparison = DefaultComparison) + { + if (string.IsNullOrEmpty(receiver) || string.IsNullOrEmpty(seekValue) || count <= 0) return -1; - /// - /// Obtains a sub-string after the last occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - ///Returns a sub-string after the last occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringAfterLast(this string value, char delimiter, string? defaultValue = null) => - value.SubstringAfterIndex(value.LastIndexOf(delimiter), 1, defaultValue); + int occurrences = 0; + int startIndex = 0; - /// - /// Obtains a sub-string after the last occurrence of the specified delimiter within the current instance. - /// - /// The current instance from which to obtain a sub-string. - /// The delimiter to find within the current instance. - /// - /// The value to return in the event that the delimiter is not found in the current instance. - /// If the default value is then the current instance is returned. - /// - /// - /// The culture, case and sort rules that will be applied when searching for the specified delimiter. - /// The default value is . - /// - /// - ///Returns a sub-string after the last occurrence of the specified delimiter within the current instance. - /// If the delimiter is not found, then the default value will be returned. - /// If the default value is , then the current instance is returned. - /// - public static string SubstringAfterLast(this string value, string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => - value.SubstringAfterIndex(value.LastIndexOf(delimiter, comparison), 1, defaultValue); + while (true) + { + int index = receiver.IndexOf(seekValue, startIndex, comparison); - /// - /// Obtains a sub-string before the nth occurrence of the specified character within the current instance. - /// If the nth occurrence is not found, returns the or the entire string if default is null. - /// - /// The current instance from which to obtain a sub-string. - /// The character to find the nth occurrence of. - /// The nth occurrence to find. - /// - /// The value to return if the nth occurrence is not found. - /// If the default value is , the current instance is returned. - /// - /// - /// A sub-string before the nth occurrence of if found; otherwise, - /// or the entire string if default is null. - /// - public static string SubstringBeforeNth(this string value, char seekValue, int count, string? defaultValue = null) - { - int index = value.NthIndexOf(seekValue, count); - return value.SubstringBeforeIndex(index, defaultValue); - } + if (index is -1) + return -1; - /// - /// Obtains a sub-string before the nth occurrence of the specified substring within the current instance. - /// If the nth occurrence is not found, returns the or the entire string if default is null. - /// - /// The current instance from which to obtain a sub-string. - /// The substring to find the nth occurrence of. - /// The nth occurrence to find. - /// - /// The value to return if the nth occurrence is not found. - /// If the default value is , the current instance is returned. - /// - /// The comparison that will be used to compare the current value and the seek value. - /// - /// A sub-string before the nth occurrence of if found; otherwise, - /// or the entire string if default is null. - /// - public static string SubstringBeforeNth(this string value, string seekValue, int count, string? defaultValue = null, StringComparison comparison = DefaultComparison) - { - int index = value.NthIndexOf(seekValue, count, comparison); - return value.SubstringBeforeIndex(index, defaultValue); - } + occurrences++; - /// - /// Obtains a sub-string after the nth occurrence of the specified character within the current instance. - /// If the nth occurrence is not found, returns the or the entire string if default is null. - /// - /// The current instance from which to obtain a sub-string. - /// The character to find the nth occurrence of. - /// The nth occurrence to find. - /// - /// The value to return if the nth occurrence is not found. - /// If the default value is , the current instance is returned. - /// - /// - /// A sub-string after the nth occurrence of if found; otherwise, - /// or the entire string if default is null. - /// - public static string SubstringAfterNth(this string value, char seekValue, int count, string? defaultValue = null) - { - int index = value.NthIndexOf(seekValue, count); - // Move 1 character after the nth occurrence index. - return value.SubstringAfterIndex(index, 1, defaultValue); - } + if (occurrences == count) + return index; - /// - /// Obtains a sub-string after the nth occurrence of the specified substring within the current instance. - /// If the nth occurrence is not found, returns the or the entire string if default is null. - /// - /// The current instance from which to obtain a sub-string. - /// The substring to find the nth occurrence of. - /// The nth occurrence to find. - /// - /// The value to return if the nth occurrence is not found. - /// If the default value is , the current instance is returned. - /// - /// The comparison that will be used to compare the current value and the seek value. - /// - /// A sub-string after the nth occurrence of if found; otherwise, - /// or the entire string if default is null. - /// - public static string SubstringAfterNth(this string value, string seekValue, int count, string? defaultValue = null, StringComparison comparison = DefaultComparison) - { - int index = value.NthIndexOf(seekValue, count, comparison); - // Move by the length of the found substring after the nth occurrence index. - int offset = (index != NotFound && !string.IsNullOrEmpty(seekValue)) ? seekValue.Length : 0; - return value.SubstringAfterIndex(index, offset, defaultValue); - } + startIndex = index + seekValue.Length; - /// - /// Converts the current instance into a new instance. - /// - /// The current from which to obtain a . - /// The encoding that will be used to convert the current into a . - /// Returns a new representation of the current instance. - public static byte[] ToByteArray(this string value, Encoding? encoding = null) => encoding.GetOrDefault().GetBytes(value); + if (startIndex >= receiver.Length) + return NotFound; + } + } - /// - /// Converts the current instance into a new instance. - /// - /// The current instance to convert. - /// An object that provides culture-specific formatting information. - /// A bit-wise combination of enumeration values that indicate the style elements that can be present. - /// Returns a new instance parsed from the current instance. - public static DateTime ToDateTime(this string value, IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => - DateTime.Parse(value, provider, styles); + /// + /// Repeats the current by the specified number of repetitions. + /// + /// The number of repetitions of the current instance. + /// Returns a new instance representing the repetition of the current instance. + public string Repeat(int count) => count > 0 ? string.Join(string.Empty, Enumerable.Repeat(receiver, count)) : string.Empty; + + /// + /// Obtains a sub-string before the specified index within the current instance. + /// + /// The index in the current from which to obtain a sub-string. + /// + /// The value to return in the event that the index is less than zero. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string before the specified index. If the index is less than zero, then the default value will be returned. + /// If the default value is , then the current instance will be returned. + /// + // ReSharper disable once HeapView.ObjectAllocation + private string SubstringBeforeIndex(int index, string? defaultValue = null) => + index <= NotFound ? defaultValue ?? receiver : receiver[..index]; + + /// + /// Obtains a sub-string after the specified index within the current instance. + /// + /// The index in the current from which to obtain a sub-string. + /// The offset from the index which marks the beginning of the sub-string. + /// + /// The value to return in the event that the index is less than zero. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string after the specified index. If the index is less than zero, then the default value will be returned. + /// If the default value is , then the current instance will be returned. + /// + // ReSharper disable once HeapView.ObjectAllocation + private string SubstringAfterIndex(int index, int offset, string? defaultValue = null) => + index <= NotFound ? defaultValue ?? receiver : receiver[(index + offset)..]; + + /// + /// Obtains a sub-string before the first occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string before the first occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringBeforeFirst(char delimiter, string? defaultValue = null) => + receiver.SubstringBeforeIndex(receiver.IndexOf(delimiter), defaultValue); + + /// + /// Obtains a sub-string before the first occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// The culture, case and sort rules that will be applied when searching for the specified delimiter. + /// The default value is . + /// + /// + /// Returns a sub-string before the first occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringBeforeFirst(string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => + receiver.SubstringBeforeIndex(receiver.IndexOf(delimiter, comparison), defaultValue); + + /// + /// Obtains a sub-string before the last occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string before the last occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringBeforeLast(char delimiter, string? defaultValue = null) => + receiver.SubstringBeforeIndex(receiver.LastIndexOf(delimiter), defaultValue); + + /// + /// Obtains a sub-string before the last occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// The culture, case and sort rules that will be applied when searching for the specified delimiter. + /// The default value is . + /// + /// + /// Returns a sub-string before the last occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringBeforeLast(string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => + receiver.SubstringBeforeIndex(receiver.LastIndexOf(delimiter, comparison), defaultValue); + + /// + /// Obtains a sub-string after the first occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string after the first occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringAfterFirst(char delimiter, string? defaultValue = null) => + receiver.SubstringAfterIndex(receiver.IndexOf(delimiter), 1, defaultValue); + + /// + /// Obtains a sub-string after the first occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// The culture, case and sort rules that will be applied when searching for the specified delimiter. + /// The default value is . + /// + /// + /// Returns a sub-string after the first occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringAfterFirst(string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => + receiver.SubstringAfterIndex(receiver.IndexOf(delimiter, comparison), delimiter.Length, defaultValue); + + /// + /// Obtains a sub-string after the last occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// Returns a sub-string after the last occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringAfterLast(char delimiter, string? defaultValue = null) => + receiver.SubstringAfterIndex(receiver.LastIndexOf(delimiter), 1, defaultValue); + + /// + /// Obtains a sub-string after the last occurrence of the specified delimiter within the current instance. + /// + /// The delimiter to find within the current instance. + /// + /// The value to return in the event that the delimiter is not found in the current instance. + /// If the default value is then the current instance is returned. + /// + /// + /// The culture, case and sort rules that will be applied when searching for the specified delimiter. + /// The default value is . + /// + /// + /// Returns a sub-string after the last occurrence of the specified delimiter within the current instance. + /// If the delimiter is not found, then the default value will be returned. + /// If the default value is , then the current instance is returned. + /// + public string SubstringAfterLast(string delimiter, string? defaultValue = null, StringComparison comparison = DefaultComparison) => + receiver.SubstringAfterIndex(receiver.LastIndexOf(delimiter, comparison), 1, defaultValue); + + /// + /// Obtains a sub-string before the nth occurrence of the specified character within the current instance. + /// If the nth occurrence is not found, returns the or the entire string if default is null. + /// + /// The character to find the nth occurrence of. + /// The nth occurrence to find. + /// + /// The value to return if the nth occurrence is not found. + /// If the default value is , the current instance is returned. + /// + /// + /// A sub-string before the nth occurrence of if found; otherwise, + /// or the entire string if default is null. + /// + public string SubstringBeforeNth(char seekValue, int count, string? defaultValue = null) + { + int index = receiver.NthIndexOf(seekValue, count); + return receiver.SubstringBeforeIndex(index, defaultValue); + } - /// - /// Converts the current instance into a new instance. - /// - /// The current instance to convert. - /// An object that provides culture-specific formatting information. - /// A bit-wise combination of enumeration values that indicate the style elements that can be present. - /// Returns a new instance parsed from the current instance. - public static DateOnly ToDateOnly(this string value, IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => - DateOnly.Parse(value, provider, styles); + /// + /// Obtains a sub-string before the nth occurrence of the specified substring within the current instance. + /// If the nth occurrence is not found, returns the or the entire string if default is null. + /// + /// The substring to find the nth occurrence of. + /// The nth occurrence to find. + /// + /// The value to return if the nth occurrence is not found. + /// If the default value is , the current instance is returned. + /// + /// The comparison that will be used to compare the current value and the seek value. + /// + /// A sub-string before the nth occurrence of if found; otherwise, + /// or the entire string if default is null. + /// + public string SubstringBeforeNth(string seekValue, int count, string? defaultValue = null, StringComparison comparison = DefaultComparison) + { + int index = receiver.NthIndexOf(seekValue, count, comparison); + return receiver.SubstringBeforeIndex(index, defaultValue); + } - /// - /// Converts the current instance into a new instance. - /// - /// The current instance to convert. - /// An object that provides culture-specific formatting information. - /// A bit-wise combination of enumeration values that indicate the style elements that can be present. - /// Returns a new instance parsed from the current instance. - public static TimeOnly ToTimeOnly(this string value, IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => - TimeOnly.Parse(value, provider, styles); + /// + /// Obtains a sub-string after the nth occurrence of the specified character within the current instance. + /// If the nth occurrence is not found, returns the or the entire string if default is null. + /// + /// The character to find the nth occurrence of. + /// The nth occurrence to find. + /// + /// The value to return if the nth occurrence is not found. + /// If the default value is , the current instance is returned. + /// + /// + /// A sub-string after the nth occurrence of if found; otherwise, + /// or the entire string if default is null. + /// + public string SubstringAfterNth(char seekValue, int count, string? defaultValue = null) + { + int index = receiver.NthIndexOf(seekValue, count); + // Move 1 character after the nth occurrence index. + return receiver.SubstringAfterIndex(index, 1, defaultValue); + } - /// - /// Returns a with all escape characters formatted as escape character literals. - /// - /// The current value. - /// Returns a with all escape characters formatted as escape character literals. - public static string ToEscapedString(this string value) - { - // ReSharper disable once HeapView.ObjectAllocation.Evident - StringBuilder result = new(); + /// + /// Obtains a sub-string after the nth occurrence of the specified substring within the current instance. + /// If the nth occurrence is not found, returns the or the entire string if default is null. + /// + /// The substring to find the nth occurrence of. + /// The nth occurrence to find. + /// + /// The value to return if the nth occurrence is not found. + /// If the default value is , the current instance is returned. + /// + /// The comparison that will be used to compare the current value and the seek value. + /// + /// A sub-string after the nth occurrence of if found; otherwise, + /// or the entire string if default is null. + /// + public string SubstringAfterNth(string seekValue, int count, string? defaultValue = null, StringComparison comparison = DefaultComparison) + { + int index = receiver.NthIndexOf(seekValue, count, comparison); + // Move by the length of the found substring after the nth occurrence index. + int offset = (index != NotFound && !string.IsNullOrEmpty(seekValue)) ? seekValue.Length : 0; + return receiver.SubstringAfterIndex(index, offset, defaultValue); + } - foreach (char c in value) + /// + /// Converts the current instance into a new array. + /// + /// The encoding that will be used to convert the current into a array. + /// Returns a new array representation of the current instance. + public byte[] ToByteArray(Encoding? encoding = null) => encoding.GetOrDefault().GetBytes(receiver); + + /// + /// Converts the current instance into a new instance. + /// + /// An object that provides culture-specific formatting information. + /// A bit-wise combination of enumeration values that indicate the style elements that can be present. + /// Returns a new instance parsed from the current instance. + public DateTime ToDateTime(IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => + DateTime.Parse(receiver, provider, styles); + + /// + /// Converts the current instance into a new instance. + /// + /// An object that provides culture-specific formatting information. + /// A bit-wise combination of enumeration values that indicate the style elements that can be present. + /// Returns a new instance parsed from the current instance. + public DateOnly ToDateOnly(IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => + DateOnly.Parse(receiver, provider, styles); + + /// + /// Converts the current instance into a new instance. + /// + /// An object that provides culture-specific formatting information. + /// A bit-wise combination of enumeration values that indicate the style elements that can be present. + /// Returns a new instance parsed from the current instance. + public TimeOnly ToTimeOnly(IFormatProvider? provider = null, DateTimeStyles styles = DefaultStyles) => + TimeOnly.Parse(receiver, provider, styles); + + /// + /// Returns a with all escape characters formatted as escape character literals. + /// + /// Returns a with all escape characters formatted as escape character literals. + public string ToEscapedString() { - switch (c) + // ReSharper disable once HeapView.ObjectAllocation.Evident + StringBuilder result = new(); + + foreach (char c in receiver) { - case '\n': - result.AppendEscaped('n'); - break; - case '\r': - result.AppendEscaped('r'); - break; - case '\t': - result.AppendEscaped('t'); - break; - case '\"': - result.AppendEscaped('"'); - break; - case '\'': - result.AppendEscaped('\''); - break; - case '\\': - result.AppendEscaped('\\'); - break; - default: - if (char.IsControl(c)) result.Append($"\\u{(int)c:X4}"); - else result.Append(c); - break; + switch (c) + { + case '\n': + result.AppendEscaped('n'); + break; + case '\r': + result.AppendEscaped('r'); + break; + case '\t': + result.AppendEscaped('t'); + break; + case '\"': + result.AppendEscaped('"'); + break; + case '\'': + result.AppendEscaped('\''); + break; + case '\\': + result.AppendEscaped('\\'); + break; + default: + if (char.IsControl(c)) result.Append($"\\u{(int)c:X4}"); + else result.Append(c); + break; + } } + + return result.ToString(); } - return result.ToString(); - } + /// + /// Tries to copy the current instance into the destination . + /// + /// The into which the current contents will be copied. + /// The number of characters written to the destination . + /// Returns if the current instance was copied into the destination ; otherwise, if the destination was too short. + public bool TryCopyTo(Span destination, out int charsWritten) + { + bool result = receiver.TryCopyTo(destination); + charsWritten = result ? receiver.Length : 0; + return result; + } - /// - /// Tries to copy the current instance into the destination . - /// - /// The current instance to copy. - /// The into which the current contents will be copied. - /// The number of characters written to the destination . - /// Returns if the current instance was copied into the destination ; otherwise, if the destination was too short. - public static bool TryCopyTo(this string value, Span destination, out int charsWritten) - { - bool result = value.TryCopyTo(destination); - charsWritten = result ? value.Length : 0; - return result; + /// + /// Wraps the current instance between the specified before and after instances. + /// + /// The that should precede the current instance. + /// The that should succeed the current instance. + /// Returns a new instance representing the current instance, wrapped between the specified before and after instances. + public string Wrap(char before, char after) => string.Concat(before.ToString(), receiver, after.ToString()); + + /// + /// Wraps the current instance between the specified before and after instances. + /// + /// The that should precede the current instance. + /// The that should succeed the current instance. + /// Returns a new instance representing the current instance, wrapped between the specified before and after instances. + public string Wrap(string before, string after) => string.Concat(before, receiver, after); } - - /// - /// Wraps the current instance between the specified before and after instances. - /// - /// The current instance to wrap. - /// The that should precede the current instance. - /// The that should succeed the current instance. - /// Returns a new instance representing the current instance, wrapped between the specified before and after instances. - public static string Wrap(this string value, char before, char after) => - string.Concat(before.ToString(), value, after.ToString()); - - /// - /// Wraps the current instance between the specified before and after instances. - /// - /// The current instance to wrap. - /// The that should precede the current instance. - /// The that should succeed the current instance. - /// Returns a new instance representing the current instance, wrapped between the specified before and after instances. - public static string Wrap(this string value, string before, string after) => - string.Concat(before, value, after); } diff --git a/OnixLabs.Core/IMemoryBinaryConvertible.cs b/OnixLabs.Core/IMemoryBinaryConvertible.cs index 9f6361b..079d33d 100644 --- a/OnixLabs.Core/IMemoryBinaryConvertible.cs +++ b/OnixLabs.Core/IMemoryBinaryConvertible.cs @@ -22,8 +22,8 @@ namespace OnixLabs.Core; public interface IMemoryBinaryConvertible { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the current instance as a new instance. ReadOnlyMemory AsReadOnlyMemory(); } diff --git a/OnixLabs.Core/ISpanBinaryConvertible.cs b/OnixLabs.Core/ISpanBinaryConvertible.cs index 1a6386c..dcaffa2 100644 --- a/OnixLabs.Core/ISpanBinaryConvertible.cs +++ b/OnixLabs.Core/ISpanBinaryConvertible.cs @@ -22,8 +22,8 @@ namespace OnixLabs.Core; public interface ISpanBinaryConvertible { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the current instance as a new instance. ReadOnlySpan AsReadOnlySpan(); } diff --git a/OnixLabs.Core/Linq/Extensions.Expression.cs b/OnixLabs.Core/Linq/Extensions.Expression.cs index 71cb41c..2be0a4e 100644 --- a/OnixLabs.Core/Linq/Extensions.Expression.cs +++ b/OnixLabs.Core/Linq/Extensions.Expression.cs @@ -20,7 +20,7 @@ namespace OnixLabs.Core.Linq; /// -/// Provides extension methods for . +/// Provides extension methods for instances. /// [EditorBrowsable(EditorBrowsableState.Never)] public static class ExpressionExtensions @@ -28,72 +28,74 @@ public static class ExpressionExtensions private const string ParameterName = "$param"; /// - /// Combines two instances into a single expression using the logical AND operator. + /// Provides extension methods for instances. /// - /// The left-hand expression to combine. - /// The right-hand expression to combine. - /// The underlying type of the expression. - /// - /// Returns a new that combines two instances - /// into a single expression using the logical AND operator. - /// - /// - /// Calling this method introduces a new expression parameter (named $param) to ensure both expressions share the same parameter. - /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. - /// - public static Expression> And(this Expression> left, Expression> right) + /// The current (left-hand) instance. + /// The underlying type of the current (left-hand) instance. + extension(Expression> receiver) { - ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); - Expression leftBody = new ReplaceParameterVisitor(left.Parameters.First(), parameter).Visit(left.Body); - Expression rightBody = new ReplaceParameterVisitor(right.Parameters.First(), parameter).Visit(right.Body); - BinaryExpression binaryExpression = Expression.AndAlso(leftBody, rightBody); + /// + /// Combines two instances into a single expression using the logical AND operator. + /// + /// The other (right-hand) expression to combine. + /// + /// Returns a new that combines two instances + /// into a single expression using the logical AND operator. + /// + /// + /// Calling this method introduces a new expression parameter (named $param) to ensure both expressions share the same parameter. + /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. + /// + public Expression> And(Expression> other) + { + ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); + Expression leftBody = new ReplaceParameterVisitor(receiver.Parameters.First(), parameter).Visit(receiver.Body); + Expression rightBody = new ReplaceParameterVisitor(other.Parameters.First(), parameter).Visit(other.Body); + BinaryExpression binaryExpression = Expression.AndAlso(leftBody, rightBody); - return Expression.Lambda>(binaryExpression, parameter); - } + return Expression.Lambda>(binaryExpression, parameter); + } - /// - /// Combines two instances into a single expression using the logical OR operator. - /// - /// The left-hand expression to combine. - /// The right-hand expression to combine. - /// The underlying type of the expression. - /// - /// Returns a new that combines two instances - /// into a single expression using the logical OR operator. - /// - /// - /// Calling this method introduces a new expression parameter (named $param) to ensure both expressions share the same parameter. - /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. - /// - public static Expression> Or(this Expression> left, Expression> right) - { - ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); - Expression leftBody = new ReplaceParameterVisitor(left.Parameters.First(), parameter).Visit(left.Body); - Expression rightBody = new ReplaceParameterVisitor(right.Parameters.First(), parameter).Visit(right.Body); - BinaryExpression binaryExpression = Expression.OrElse(leftBody, rightBody); + /// + /// Combines two instances into a single expression using the logical OR operator. + /// + /// The other (right-hand) expression to combine. + /// + /// Returns a new that combines two instances + /// into a single expression using the logical OR operator. + /// + /// + /// Calling this method introduces a new expression parameter (named $param) to ensure both expressions share the same parameter. + /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. + /// + public Expression> Or(Expression> other) + { + ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); + Expression leftBody = new ReplaceParameterVisitor(receiver.Parameters.First(), parameter).Visit(receiver.Body); + Expression rightBody = new ReplaceParameterVisitor(other.Parameters.First(), parameter).Visit(other.Body); + BinaryExpression binaryExpression = Expression.OrElse(leftBody, rightBody); - return Expression.Lambda>(binaryExpression, parameter); - } + return Expression.Lambda>(binaryExpression, parameter); + } - /// - /// Negates the current instance using the logical NOT operator. - /// - /// The expression to negate. - /// The underlying type of the expression. - /// - /// Returns a new that negates the current instance using the logical NOT operator. - /// - /// - /// Calling this method introduces a new expression parameter (named $param) to ensure a uniform parameter expression. - /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. - /// - public static Expression> Not(this Expression> expression) - { - ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); - Expression expressionBody = new ReplaceParameterVisitor(expression.Parameters.First(), parameter).Visit(expression.Body); + /// + /// Negates the current instance using the logical NOT operator. + /// + /// + /// Returns a new that negates the current instance using the logical NOT operator. + /// + /// + /// Calling this method introduces a new expression parameter (named $param) to ensure a uniform parameter expression. + /// Internal or nested lambda parameters that do not match the replaced parameter remain untouched. + /// + public Expression> Not() + { + ParameterExpression parameter = Expression.Parameter(typeof(T), ParameterName); + Expression expressionBody = new ReplaceParameterVisitor(receiver.Parameters.First(), parameter).Visit(receiver.Body); - UnaryExpression unaryExpression = Expression.Not(expressionBody); - return Expression.Lambda>(unaryExpression, parameter); + UnaryExpression unaryExpression = Expression.Not(expressionBody); + return Expression.Lambda>(unaryExpression, parameter); + } } /// diff --git a/OnixLabs.Core/Linq/Extensions.IEnumerable.cs b/OnixLabs.Core/Linq/Extensions.IEnumerable.cs index 8590a1d..01a1904 100644 --- a/OnixLabs.Core/Linq/Extensions.IEnumerable.cs +++ b/OnixLabs.Core/Linq/Extensions.IEnumerable.cs @@ -25,7 +25,7 @@ namespace OnixLabs.Core.Linq; /// -/// Provides LINQ-like extension methods for . +/// Provides LINQ-like extension methods for and instances. /// // ReSharper disable InconsistentNaming [EditorBrowsable(EditorBrowsableState.Never)] @@ -42,473 +42,486 @@ public static class IEnumerableExtensions private const string ActionNullExceptionMessage = "Action must not be null."; /// - /// Determines whether all elements of the current are equal by a specified property. + /// Provides LINQ-like extension methods for instances. /// - /// The current on which to perform the operation. - /// The selector function which will be used to select the desired property from each element. - /// The equality comparer that will be used to compare objects of type , or to use the default equality comparer. - /// The underlying type of the . - /// The underlying type of each selected element. - /// Returns if all selected element properties are equal; otherwise . - public static bool AllEqualBy(this IEnumerable enumerable, Func selector, IEqualityComparer? comparer = null) + /// The current instance. + extension(IEnumerable? enumerable) { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(selector, SelectorNullExceptionMessage, nameof(selector)); + /// + /// Obtains a number that represents how many elements are in the current . + /// + /// Returns a number that represents how many elements are in the current . + public int Count() + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - using IEnumerator enumerator = enumerable.GetEnumerator(); + // ReSharper disable once GenericEnumeratorNotDisposed + IEnumerator enumerator = enumerable.GetEnumerator(); - // AllEqualBy of empty IEnumerable is considered true. - if (!enumerator.MoveNext()) return true; + int count = 0; - TProperty firstValue = selector(enumerator.Current); + while (enumerator.MoveNext()) + checked + { + ++count; + } - while (enumerator.MoveNext()) - if (!comparer.GetOrDefault().Equals(firstValue, selector(enumerator.Current))) - return false; + return count; + } - return true; - } + /// + /// Performs the specified for each element of the current . + /// + /// The to perform for each element. + public void ForEach(Action action) + { + if (enumerable is null) + return; - /// - /// Determines whether any elements of the current are equal by a specified property. - /// - /// The current on which to perform the operation. - /// The selector function which will be used to select the desired property from each element. - /// The equality comparer that will be used to compare objects of type , or to use the default equality comparer. - /// The underlying type of the . - /// The underlying type of each selected element. - /// Returns if any selected element properties are equal; otherwise . - public static bool AnyEqualBy(this IEnumerable enumerable, Func selector, IEqualityComparer? comparer = null) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(selector, SelectorNullExceptionMessage, nameof(selector)); + RequireNotNull(action, ActionNullExceptionMessage); - // ReSharper disable once HeapView.ObjectAllocation.Evident - HashSet seenValues = new(comparer); + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (object? element in enumerable) + action(element); + } - // ReSharper disable once LoopCanBeConvertedToQuery, HeapView.ObjectAllocation.Possible - foreach (T item in enumerable) + /// + /// Gets the content hash code of the elements of the current . + /// + /// Returns the computed content hash code of the current . + public int GetContentHashCode() { - TProperty value = selector(item); + if (enumerable is null) + return 0; - if (seenValues.Add(value)) continue; + HashCode result = new(); - return true; + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (object? element in enumerable) + result.Add(element); + + return result.ToHashCode(); } - return false; - } + /// + /// Determines whether the current is empty. + /// + /// Returns if the is empty; otherwise, . + public bool IsEmpty() => enumerable.LongCount() is 0; + + /// + /// Determines whether the current is not empty. + /// + /// Returns if the is not empty; otherwise, . + public bool IsNotEmpty() => !enumerable.IsEmpty(); + + /// + /// Determines whether the current contains a single element. + /// + /// Returns if the contains a single element; otherwise, . + public bool IsSingle() => enumerable.LongCount() is 1; + + /// + /// Determines whether the current contains an even number of elements. + /// + /// Returns if the contains an even number of elements; otherwise, . + public bool IsCountEven() => (enumerable.LongCount() & 1) is 0; + + /// + /// Determines whether the current contains an odd number of elements. + /// + /// Returns if the contains an odd number of elements; otherwise, . + public bool IsCountOdd() => !enumerable.IsCountEven(); + + /// + /// Joins the elements of the current into a new instance. + /// + /// The separator which will appear between joined elements. + /// Returns the elements of the current , joined into a new instance. + public string JoinToString(string separator = CollectionSeparator) + { + if (enumerable is null) + return string.Empty; - /// - /// Obtains a number that represents how many elements are in the current . - /// - /// The current on which to perform the operation. - /// Returns a number that represents how many elements are in the current . - public static int Count(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + // ReSharper disable once HeapView.ObjectAllocation.Evident + StringBuilder builder = new(); - return Enumerable.Count(enumerable.Cast()); - } + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (object? element in enumerable) + builder.Append(element.ToStringOrNull()).Append(separator); - /// - /// Obtains a number that represents how many elements in the current do not satisfy the specified predicate condition. - /// - /// The current on which to perform the operation. - /// The function to test each element for a condition. - /// The underlying type of the . - /// Returns a number that represents how many elements in the current do not satisfy the specified predicate condition. - public static int CountNot(this IEnumerable enumerable, Func predicate) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(predicate, PredicateNullExceptionMessage, nameof(predicate)); + return builder.TrimEnd(separator).ToString(); + } + + /// + /// Obtains a number that represents how many elements are in the current . + /// + /// Returns a number that represents how many elements are in the current . + // ReSharper disable once MemberCanBePrivate.Global + public long LongCount() + { + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - int result = 0; + // ReSharper disable once GenericEnumeratorNotDisposed + IEnumerator enumerator = enumerable.GetEnumerator(); - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (T element in enumerable) - if (!predicate(element)) + long count = 0; + + while (enumerator.MoveNext()) checked { - ++result; + ++count; } - return result; - } - - /// - /// Obtains the first element of the current that satisfies the specified predicate; - /// otherwise if no such element is found. - /// - /// The current from which to return the first satisfactory element. - /// The function to test each element for a condition. - /// The underlying type of the . - /// - /// Returns the first element of the current that satisfies the specified predicate; - /// otherwise if no such element is found. - /// - public static Optional FirstOrNone(this IEnumerable enumerable, Func? predicate = null) where T : notnull - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - - return Optional.Of(enumerable.FirstOrDefault(predicate ?? (_ => true))); - } - - /// - /// Performs the specified for each element of the current . - /// - /// The current over which to iterate. - /// The to perform for each element. - public static void ForEach(this IEnumerable enumerable, Action action) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(action, ActionNullExceptionMessage, nameof(action)); + return count; + } - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (object? element in enumerable) action(element); + /// + /// Formats the current as a collection string. + /// + /// Returns a new instance representing the current . + public string ToCollectionString() => enumerable is null + ? string.Empty + : enumerable.JoinToString().Wrap(CollectionOpenBracket, CollectionCloseBracket); } /// - /// Performs the specified for each element of the current . + /// Provides LINQ-like extension methods for instances. /// - /// The current over which to iterate. - /// The to perform for each element. - /// The underlying type of the . - public static void ForEach(this IEnumerable enumerable, Action action) + /// The current instance. + extension(IEnumerable? enumerable) { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(action, ActionNullExceptionMessage, nameof(action)); - - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (T element in enumerable) action(element); - } + /// + /// Determines whether all elements of the current are equal by a specified property. + /// + /// The selector function which will be used to select the desired property from each element. + /// The equality comparer that will be used to compare objects of type , or to use the default equality comparer. + /// The underlying type of each selected element. + /// Returns if all selected element properties are equal; otherwise . + public bool AllEqualBy(Func selector, IEqualityComparer? comparer = null) + { + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(selector, SelectorNullExceptionMessage); - /// - /// Gets the content hash code of the elements of the current . - /// - /// The current from which to compute a content hash code. - /// Returns the computed content hash code of the current . - public static int GetContentHashCode(this IEnumerable? enumerable) - { - if (enumerable is null) return 0; + using IEnumerator enumerator = enumerable.GetEnumerator(); - HashCode result = new(); + // AllEqualBy of empty IEnumerable is considered true. + if (!enumerator.MoveNext()) + return true; - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (object? element in enumerable) result.Add(element); + TProperty firstValue = selector(enumerator.Current); + IEqualityComparer nonNullComparer = comparer.GetOrDefault(); - return result.ToHashCode(); - } + while (enumerator.MoveNext()) + if (!nonNullComparer.Equals(firstValue, selector(enumerator.Current))) + return false; - /// - /// Gets the content hash code of the elements of the current . - /// - /// The current from which to compute a content hash code. - /// The underlying type of the . - /// Returns the computed content hash code of the current . - public static int GetContentHashCode(this IEnumerable? enumerable) - { - if (enumerable is null) return 0; + return true; + } - HashCode result = new(); + /// + /// Determines whether any elements of the current are equal by a specified property. + /// + /// The selector function which will be used to select the desired property from each element. + /// The equality comparer that will be used to compare objects of type , or to use the default equality comparer. + /// The underlying type of each selected element. + /// Returns if any selected element properties are equal; otherwise . + public bool AnyEqualBy(Func selector, IEqualityComparer? comparer = null) + { + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(selector, SelectorNullExceptionMessage); - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (T element in enumerable) result.Add(element); + using IEnumerator enumerator = enumerable.GetEnumerator(); - return result.ToHashCode(); - } + // AnyEqualBy of empty IEnumerable is considered false. + if (!enumerator.MoveNext()) + return false; - /// - /// Determines whether the current is empty. - /// - /// The current on which to perform the operation. - /// Returns if the is empty; otherwise, . - public static bool IsEmpty(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + TProperty firstValue = selector(enumerator.Current); + IEqualityComparer nonNullComparer = comparer.GetOrDefault(); - // ReSharper disable once LoopCanBeConvertedToQuery, HeapView.ObjectAllocation.Possible - foreach (object? _ in enumerable) return false; + while (enumerator.MoveNext()) + if (nonNullComparer.Equals(firstValue, selector(enumerator.Current))) + return true; - return true; - } + return false; + } - /// - /// Determines whether the current is empty. - /// - /// The current on which to perform the operation. - /// The underlying type of the . - /// Returns if the is empty; otherwise, . - public static bool IsEmpty(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + /// + /// Obtains a number that represents how many elements in the current do not satisfy the specified predicate condition. + /// + /// The function to test each element for a condition. + /// Returns a number that represents how many elements in the current do not satisfy the specified predicate condition. + public int CountNot(Func predicate) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(predicate, PredicateNullExceptionMessage); - // ReSharper disable once LoopCanBeConvertedToQuery, HeapView.ObjectAllocation.Possible - foreach (T _ in enumerable) return false; + int result = 0; - return true; - } + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (T element in enumerable) + if (!predicate(element)) + checked + { + ++result; + } - /// - /// Determines whether the current is not empty. - /// - /// The current on which to perform the operation. - /// Returns if the is not empty; otherwise, . - public static bool IsNotEmpty(this IEnumerable enumerable) => !enumerable.IsEmpty(); + return result; + } - /// - /// Determines whether the current is not empty. - /// - /// The current on which to perform the operation. - /// The underlying type of the . - /// Returns if the is not empty; otherwise, . - public static bool IsNotEmpty(this IEnumerable enumerable) => !enumerable.IsEmpty(); + /// + /// Performs the specified for each element of the current . + /// + /// The to perform for each element. + public void ForEach(Action action) + { + if (enumerable is null) + return; - /// - /// Determines whether the current contains a single element. - /// - /// The current on which to perform the operation. - /// Returns if the contains a single element; otherwise, . - public static bool IsSingle(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + RequireNotNull(action, ActionNullExceptionMessage); - long count = 0; + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (T element in enumerable) + action(element); + } - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (object? _ in enumerable) + /// + /// Gets the content hash code of the elements of the current . + /// + /// Returns the computed content hash code of the current . + public int GetContentHashCode() { - checked - { - ++count; - } - - if (count > 1) return false; - } + if (enumerable is null) + return 0; - return count is 1; - } + HashCode result = new(); - /// - /// Determines whether the current contains a single element. - /// - /// The current on which to perform the operation. - /// The underlying type of the . - /// Returns if the contains a single element; otherwise, . - public static bool IsSingle(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + // ReSharper disable once HeapView.ObjectAllocation.Possible + foreach (T element in enumerable) + result.Add(element); - long count = 0; + return result.ToHashCode(); + } - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (T _ in enumerable) + /// + /// Determines whether the current is empty. + /// + /// Returns if the is empty; otherwise, . + public bool IsEmpty() => enumerable.LongCount() is 0; + + /// + /// Determines whether the current is not empty. + /// + /// Returns if the is not empty; otherwise, . + public bool IsNotEmpty() => !enumerable.IsEmpty(); + + /// + /// Determines whether the current contains a single element. + /// + /// Returns if the contains a single element; otherwise, . + public bool IsSingle() => enumerable.LongCount() is 1; + + /// + /// Determines whether the current contains an even number of elements. + /// + /// The function to test each element for a condition. + /// Returns if the contains an even number of elements; otherwise, . + public bool IsCountEven(Func? predicate = null) { - checked - { - ++count; - } + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - if (count > 1) return false; + return (enumerable.LongCount(predicate ?? (_ => true)) & 1) is 0; } - return count is 1; - } + /// + /// Determines whether the current contains an odd number of elements. + /// + /// The function to test each element for a condition. + /// Returns if the contains an odd number of elements; otherwise, . + public bool IsCountOdd(Func? predicate = null) => !enumerable.IsCountEven(predicate); + + /// + /// Joins the elements of the current into a new instance. + /// + /// The separator which will appear between joined elements. + /// Returns the elements of the current , joined into a new instance. + public string JoinToString(string separator = CollectionSeparator) + { + if (enumerable is null) + return string.Empty; - /// - /// Determines whether the current contains an even number of elements. - /// - /// The current on which to perform the operation. - /// Returns if the contains an even number of elements; otherwise, . - public static bool IsCountEven(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + // ReSharper disable once HeapView.ObjectAllocation.Evident + StringBuilder builder = new(); - return enumerable.LongCount() % 2 is 0; - } - - /// - /// Determines whether the current contains an even number of elements. - /// - /// The current on which to perform the operation. - /// The function to test each element for a condition. - /// The underlying type of the . - /// Returns if the contains an even number of elements; otherwise, . - public static bool IsCountEven(this IEnumerable enumerable, Func? predicate = null) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + // ReSharper disable once HeapView.ObjectAllocation.Possible, HeapView.PossibleBoxingAllocation + foreach (T element in enumerable) + builder.Append(element.ToStringOrNull()).Append(separator); - return enumerable.LongCount(predicate ?? (_ => true)) % 2 is 0; - } + return builder.TrimEnd(separator).ToString(); + } - /// - /// Determines whether the current contains an odd number of elements. - /// - /// The current on which to perform the operation. - /// Returns if the contains an odd number of elements; otherwise, . - public static bool IsCountOdd(this IEnumerable enumerable) => !enumerable.IsCountEven(); + /// + /// Determines whether none of the elements of the current satisfy the specified predicate condition. + /// + /// The function to test each element for a condition. + /// Returns if none of the elements of the current satisfy the specified predicate condition; otherwise, . + public bool None(Func predicate) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - /// - /// Determines whether the current contains an odd number of elements. - /// - /// The current on which to perform the operation. - /// The function to test each element for a condition. - /// The underlying type of the . - /// Returns if the contains an odd number of elements; otherwise, . - public static bool IsCountOdd(this IEnumerable enumerable, Func? predicate = null) => !enumerable.IsCountEven(predicate); + return !enumerable.Any(predicate); + } - /// - /// Joins the elements of the current into a new instance. - /// - /// The current to join. - /// The separator which will appear between joined elements. - /// Returns the elements of the current , joined into a new instance. - public static string JoinToString(this IEnumerable enumerable, string separator = CollectionSeparator) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + /// Determines whether two sequences are , or equal by comparing their elements by using a specified . + /// An to compare to the first sequence. + /// An to use to compare elements. + /// Returns if the two source sequences are , or of equal length and their corresponding elements compare equal according to ; otherwise, . + public bool SequenceEqualOrNull(IEnumerable? other, IEqualityComparer? comparer = null) + { + if (enumerable is null || other is null) + return enumerable is null && other is null; - // ReSharper disable once HeapView.ObjectAllocation.Evident - StringBuilder builder = new(); + return enumerable.SequenceEqual(other, comparer.GetOrDefault()); + } - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (object? element in enumerable) builder.Append(element.ToStringOrNull()).Append(separator); + /// + /// Calculates the sum of the elements of the current . + /// + /// The selector function which will be used to select each property from each element. + /// The underlying type of each element to sum. + /// Returns the sum of the elements of the current . + public TResult SumBy(Func selector) where TResult : INumberBase + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(selector, SelectorNullExceptionMessage); - builder.TrimEnd(separator); + return enumerable.Select(selector).Sum(); + } - return builder.ToString(); - } + /// + /// Filters a sequence of values based on a specification. + /// + /// The to filter by. + /// Returns an that contains elements from the input sequence that satisfy the specification. + public IEnumerable Where(Specification specification) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(specification, SpecificationNullExceptionMessage); - /// - /// Joins the elements of the current into a new instance. - /// - /// The current to join. - /// The separator which will appear between joined elements. - /// The underlying type of the . - /// Returns the elements of the current , joined into a new instance. - public static string JoinToString(this IEnumerable enumerable, string separator = CollectionSeparator) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + return enumerable.Where(specification.Criteria.Compile()); + } - // ReSharper disable once HeapView.ObjectAllocation.Evident - StringBuilder builder = new(); + /// + /// Filters a sequence of values based on a negated specification. + /// + /// The to filter by. + /// Returns an that contains elements from the input sequence that satisfy the negated specification. + public IEnumerable WhereNot(Specification specification) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(specification, SpecificationNullExceptionMessage); - // ReSharper disable once HeapView.ObjectAllocation.Possible, HeapView.PossibleBoxingAllocation - foreach (T element in enumerable) builder.Append(element.ToStringOrNull()).Append(separator); + return enumerable.Where(specification.Not().Criteria.Compile()); + } - builder.TrimEnd(separator); + /// + /// Filters the current elements that do not satisfy the specified predicate condition. + /// + /// The function to test each element for a condition. + /// Returns a new that contains elements that do not satisfy the condition. + public IEnumerable WhereNot(Func predicate) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + RequireNotNull(predicate, PredicateNullExceptionMessage); + + // ReSharper disable once LoopCanBeConvertedToQuery, HeapView.ObjectAllocation.Possible + foreach (T element in enumerable) + if (!predicate(element)) + yield return element; + } - return builder.ToString(); + /// + /// Formats the current as a collection string. + /// + /// Returns a new instance representing the current . + public string ToCollectionString() => enumerable is null + ? string.Empty + : enumerable.JoinToString().Wrap(CollectionOpenBracket, CollectionCloseBracket); } /// - /// Obtains the last element of the current that satisfies the specified predicate; - /// otherwise if no such element is found. + /// Provides LINQ-like extension methods for instances whose elements are not null. /// - /// The current from which to return the last satisfactory element. - /// The function to test each element for a condition. - /// The underlying type of the . - /// - /// Returns the last element of the current that satisfies the specified predicate; - /// otherwise if no such element is found. - /// - public static Optional LastOrNone(this IEnumerable enumerable, Func? predicate = null) where T : notnull + /// The current instance. + extension(IEnumerable? enumerable) where T : notnull { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + /// + /// Obtains the first element of the current that satisfies the specified predicate; + /// otherwise if no such element is found. + /// + /// The function to test each element for a condition. + /// + /// Returns the first element of the current that satisfies the specified predicate; + /// otherwise if no such element is found. + /// + public Optional FirstOrNone(Func? predicate = null) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - return Optional.Of(enumerable.LastOrDefault(predicate ?? (_ => true))); - } + return Optional.Of(enumerable.FirstOrDefault(predicate ?? (_ => true))); + } - /// - /// Obtains a number that represents how many elements are in the current . - /// - /// The current on which to perform the operation. - /// Returns a number that represents how many elements are in the current . - // ReSharper disable once MemberCanBePrivate.Global - public static long LongCount(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + /// + /// Obtains the last element of the current that satisfies the specified predicate; + /// otherwise if no such element is found. + /// + /// The function to test each element for a condition. + /// + /// Returns the last element of the current that satisfies the specified predicate; + /// otherwise if no such element is found. + /// + public Optional LastOrNone(Func? predicate = null) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); + + return Optional.Of(enumerable.LastOrDefault(predicate ?? (_ => true))); + } - long count = 0; + /// + /// Obtains a single element of the current that satisfies the specified predicate; + /// otherwise if no such element is found, + /// or if the current contains more than one matching element. + /// + /// The function to test each element for a condition. + /// + /// Returns a single element of the current that satisfies the specified predicate; + /// otherwise if no such element is found, + /// or if the current contains more than one matching element. + /// + public Result> SingleOrNone(Func? predicate = null) + { + // ReSharper disable PossibleMultipleEnumeration + RequireNotNull(enumerable, EnumerableNullExceptionMessage); - // ReSharper disable once HeapView.ObjectAllocation.Possible - foreach (object? _ in enumerable) - checked + try { - ++count; + return Optional.Of(enumerable.SingleOrDefault(predicate ?? (_ => true))); + } + catch (Exception exception) + { + return exception; } - - return count; - } - - /// - /// Determines whether none of the elements of the current satisfy the specified predicate condition. - /// - /// The current on which to perform the operation. - /// The function to test each element for a condition. - /// The underlying type of the . - /// Returns if none of the elements of the current satisfy the specified predicate condition; otherwise, . - public static bool None(this IEnumerable enumerable, Func predicate) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - - return !enumerable.Any(predicate); - } - - /// Determines whether two sequences are , or equal by comparing their elements by using a specified . - /// An to compare to . - /// An to compare to the first sequence. - /// An to use to compare elements. - /// The underlying type of the . - /// Returns if the two source sequences are , or of equal length and their corresponding elements compare equal according to ; otherwise, . - public static bool SequenceEqualOrNull(this IEnumerable? enumerable, IEnumerable? other, IEqualityComparer? comparer = null) - { - if (enumerable is null || other is null) return enumerable is null && other is null; - return enumerable.SequenceEqual(other, comparer.GetOrDefault()); - } - - /// - /// Obtains a single element of the current that satisfies the specified predicate; - /// otherwise if no such element is found, - /// or if the current contains more than one matching element. - /// - /// The current from which to return a single satisfactory element. - /// The function to test each element for a condition. - /// The underlying type of the . - /// - /// Returns a single element of the current that satisfies the specified predicate; - /// otherwise if no such element is found, - /// or if the current contains more than one matching element. - /// - public static Result> SingleOrNone(this IEnumerable enumerable, Func? predicate = null) where T : notnull - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - - try - { - return Optional.Of(enumerable.SingleOrDefault(predicate ?? (_ => true))); - } - catch (Exception exception) - { - return exception; } } @@ -521,79 +534,11 @@ public static Result> SingleOrNone(this IEnumerable enumerable public static T Sum(this IEnumerable enumerable) where T : INumberBase { // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + RequireNotNull(enumerable, EnumerableNullExceptionMessage); return enumerable.IsEmpty() ? T.Zero : enumerable.Aggregate((left, right) => left + right); } - /// - /// Calculates the sum of the elements of the current . - /// - /// The current to sum. - /// The selector function which will be used to select each property from each element. - /// The underlying type of the . - /// The underlying type of each element to sum. - /// Returns the sum of the elements of the current . - public static TResult SumBy(this IEnumerable enumerable, Func selector) where TResult : INumberBase - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(selector, SelectorNullExceptionMessage, nameof(selector)); - - return enumerable.Select(selector).Sum(); - } - - /// - /// Filters a sequence of values based on a specification. - /// - /// The current to filter. - /// The to filter by. - /// The underlying type of the . - /// Returns an that contains elements from the input sequence that satisfy the specification. - public static IEnumerable Where(this IEnumerable enumerable, Specification specification) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(specification, SpecificationNullExceptionMessage, nameof(specification)); - - return enumerable.Where(specification.Criteria.Compile()); - } - - /// - /// Filters a sequence of values based on a negated specification. - /// - /// The current to filter. - /// The to filter by. - /// The underlying type of the . - /// Returns an that contains elements from the input sequence that satisfy the negated specification. - public static IEnumerable WhereNot(this IEnumerable enumerable, Specification specification) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(specification, SpecificationNullExceptionMessage, nameof(specification)); - - return enumerable.Where(specification.Not().Criteria.Compile()); - } - - /// - /// Filters the current elements that do not satisfy the specified predicate condition. - /// - /// The current on which to perform the operation. - /// The function to test each element for a condition. - /// The underlying type of the . - /// Returns a new that contains elements that do not satisfy the condition. - public static IEnumerable WhereNot(this IEnumerable enumerable, Func predicate) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - RequireNotNull(predicate, PredicateNullExceptionMessage, nameof(predicate)); - - // ReSharper disable once LoopCanBeConvertedToQuery, HeapView.ObjectAllocation.Possible - foreach (T element in enumerable) - if (!predicate(element)) - yield return element; - } - /// /// Filters the current elements that are not . /// @@ -603,7 +548,7 @@ public static IEnumerable WhereNot(this IEnumerable enumerable, Func WhereNotNull(this IEnumerable enumerable) where T : class { // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + RequireNotNull(enumerable, EnumerableNullExceptionMessage); return enumerable.Where(element => element is not null)!; } @@ -617,38 +562,11 @@ public static IEnumerable WhereNotNull(this IEnumerable enumerable) wh public static IEnumerable WhereNotNull(this IEnumerable enumerable) where T : struct { // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + RequireNotNull(enumerable, EnumerableNullExceptionMessage); return enumerable.Where(element => element.HasValue).Select(element => element!.Value); } - /// - /// Formats the current as a collection string. - /// - /// The current to format. - /// Returns a new instance representing the current . - public static string ToCollectionString(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - - return enumerable.JoinToString().Wrap(CollectionOpenBracket, CollectionCloseBracket); - } - - /// - /// Formats the current as a collection string. - /// - /// The current to format. - /// The underlying type of the . - /// Returns a new instance representing the current . - public static string ToCollectionString(this IEnumerable enumerable) - { - // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); - - return enumerable.JoinToString().Wrap(CollectionOpenBracket, CollectionCloseBracket); - } - /// /// Formats the current as a collection string. /// @@ -661,7 +579,7 @@ public static string ToCollectionString(this IEnumerable enumerable) public static string ToCollectionString(this IEnumerable enumerable, string format, IFormatProvider? provider = null) where T : IFormattable { // ReSharper disable PossibleMultipleEnumeration - RequireNotNull(enumerable, EnumerableNullExceptionMessage, nameof(enumerable)); + RequireNotNull(enumerable, EnumerableNullExceptionMessage); // ReSharper disable once HeapView.DelegateAllocation return enumerable.Select(element => element.ToString(format, provider)).ToCollectionString(); diff --git a/OnixLabs.Core/Linq/Extensions.IQueryable.cs b/OnixLabs.Core/Linq/Extensions.IQueryable.cs index 2e398dd..d85c128 100644 --- a/OnixLabs.Core/Linq/Extensions.IQueryable.cs +++ b/OnixLabs.Core/Linq/Extensions.IQueryable.cs @@ -18,7 +18,7 @@ namespace OnixLabs.Core.Linq; /// -/// Provides LINQ-like extension methods for . +/// Provides LINQ-like extension methods for instances. /// // ReSharper disable InconsistentNaming [EditorBrowsable(EditorBrowsableState.Never)] @@ -28,32 +28,36 @@ public static class IQueryableExtensions private const string SpecificationNullExceptionMessage = "Specification must not be null."; /// - /// Filters a sequence of values based on a specification. + /// Provides LINQ-like extension methods for instances. /// - /// The current to filter. - /// The to filter by. - /// The underlying type of the . - /// Returns an that contains elements from the input sequence that satisfy the specification. - public static IQueryable Where(this IQueryable queryable, Specification specification) + /// The current instance. + /// The underlying type of the current instance. + extension(IQueryable queryable) { - RequireNotNull(queryable, QueryableNullExceptionMessage, nameof(queryable)); - RequireNotNull(specification, SpecificationNullExceptionMessage, nameof(specification)); + /// + /// Filters a sequence of values based on a specification. + /// + /// The to filter by. + /// Returns an that contains elements from the input sequence that satisfy the specification. + public IQueryable Where(Specification specification) + { + RequireNotNull(queryable, QueryableNullExceptionMessage); + RequireNotNull(specification, SpecificationNullExceptionMessage); - return queryable.Where(specification.Criteria); - } + return queryable.Where(specification.Criteria); + } - /// - /// Filters a sequence of values based on a negated specification. - /// - /// The current to filter. - /// The to filter by. - /// The underlying type of the . - /// Returns an that contains elements from the input sequence that satisfy the negated specification. - public static IQueryable WhereNot(this IQueryable queryable, Specification specification) - { - RequireNotNull(queryable, QueryableNullExceptionMessage, nameof(queryable)); - RequireNotNull(specification, SpecificationNullExceptionMessage, nameof(specification)); + /// + /// Filters a sequence of values based on a negated specification. + /// + /// The to filter by. + /// Returns an that contains elements from the input sequence that satisfy the negated specification. + public IQueryable WhereNot(Specification specification) + { + RequireNotNull(queryable, QueryableNullExceptionMessage); + RequireNotNull(specification, SpecificationNullExceptionMessage); - return queryable.Where(specification.Not().Criteria); + return queryable.Where(specification.Not().Criteria); + } } } diff --git a/OnixLabs.Core/Optional.cs b/OnixLabs.Core/Optional.cs index 109c3ea..8c0868e 100644 --- a/OnixLabs.Core/Optional.cs +++ b/OnixLabs.Core/Optional.cs @@ -94,7 +94,7 @@ public static Optional Of(TStruct? value) where TStruct : stru /// the specified value is not ; otherwise, the underlying value is . /// // ReSharper disable once HeapView.ObjectAllocation.Evident - public static Some Some(T value) => new(RequireNotNull(value, "Value must not be null.", nameof(value))); + public static Some Some(T value) => new(RequireNotNull(value, "Value must not be null.")); /// /// Creates a new instance of the class, where the underlying value is present if diff --git a/OnixLabs.Core/Preconditions.cs b/OnixLabs.Core/Preconditions.cs index 335d095..6c38c46 100644 --- a/OnixLabs.Core/Preconditions.cs +++ b/OnixLabs.Core/Preconditions.cs @@ -13,6 +13,8 @@ // limitations under the License. using System; +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; using OnixLabs.Core.Linq; namespace OnixLabs.Core; @@ -33,277 +35,368 @@ public static class Preconditions private const string ArgumentOutOfRange = "Argument must be within range."; /// - /// Performs a general pre-condition check that fails when the specified condition is . + /// Provides with static extension methods for performing pre-conditions and guard clauses. /// - /// The condition to check. - /// The exception message to throw in the event that the specified condition is . - /// If the specified condition is . - public static void Check(bool condition, string message = ArgumentFailed) + extension(InvalidOperationException) { - if (!condition) throw new InvalidOperationException(message); - } + /// + /// Performs a general pre-condition check that fails when the specified condition is . + /// + /// The condition to check. + /// The exception message to throw in the event that the specified condition is . + /// If the specified condition is . + public static void Check(bool condition, string message = ArgumentFailed) + { + if (!condition) throw new InvalidOperationException(message); + } - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// Returns the current as a instance. - /// If the specified is not of type . - public static Failure CheckIsFailure(Result result, string message = ArgumentIsNotFailure) => - result as Failure ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// Returns the current as a instance. + /// If the specified is not of type . + public static Failure CheckIsFailure(Result result, string message = ArgumentIsNotFailure) => + result as Failure ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// Returns the current as a instance. - /// If the specified is not of type . - public static Success CheckIsSuccess(Result result, string message = ArgumentIsNotSuccess) => - result as Success ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// Returns the current as a instance. + /// If the specified is not of type . + public static Success CheckIsSuccess(Result result, string message = ArgumentIsNotSuccess) => + result as Success ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Failure CheckIsFailure(Result result, string message = ArgumentIsNotFailure) => - result as Failure ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Failure CheckIsFailure(Result result, string message = ArgumentIsNotFailure) => + result as Failure ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Success CheckIsSuccess(Result result, string message = ArgumentIsNotSuccess) => - result as Success ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Success CheckIsSuccess(Result result, string message = ArgumentIsNotSuccess) => + result as Success ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static None CheckIsNone(Optional optional, string message = ArgumentIsNotNone) where T : notnull => - optional as None ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static None CheckIsNone(Optional optional, string message = ArgumentIsNotNone) where T : notnull => + optional as None ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Some CheckIsSome(Optional optional, string message = ArgumentIsNotSome) where T : notnull => - optional as Some ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Some CheckIsSome(Optional optional, string message = ArgumentIsNotSome) where T : notnull => + optional as Some ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails if the specified value is . - /// - /// The nullable value to check. - /// The exception message to throw in the event that the specified value is . - /// The underlying type of the value. - /// Returns a non-null value of the specified type. - /// If the specified value is . - public static T CheckNotNull(T? value, string message = ArgumentNull) => - value ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails if the specified value is . + /// + /// The nullable value to check. + /// The exception message to throw in the event that the specified value is . + /// The underlying type of the value. + /// Returns a non-null value of the specified type. + /// If the specified value is . + public static T CheckNotNull(T? value, string message = ArgumentNull) => + value ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails if the specified value is . - /// - /// The nullable value to check. - /// The exception message to throw in the event that the specified value is . - /// The underlying type of the value. - /// Returns a non-null value of the specified type. - /// If the specified value is . - public static T CheckNotNull(T? value, string message = ArgumentNull) where T : struct => - value ?? throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails if the specified value is . + /// + /// The nullable value to check. + /// The exception message to throw in the event that the specified value is . + /// The underlying type of the value. + /// Returns a non-null value of the specified type. + /// If the specified value is . + public static T CheckNotNull(T? value, string message = ArgumentNull) where T : struct => + value ?? throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails if the specified value is or an empty string. - /// - /// The value to check. - /// The exception message to throw in the event that the specified value is or an empty string. - /// Returns a non-null, non-empty value. - /// If the specified value is or an empty string. - public static string CheckNotNullOrEmpty(string? value, string message = ArgumentNullOrEmpty) => - !string.IsNullOrEmpty(value) ? value : throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails if the specified value is or an empty string. + /// + /// The value to check. + /// The exception message to throw in the event that the specified value is or an empty string. + /// Returns a non-null, non-empty value. + /// If the specified value is or an empty string. + public static string CheckNotNullOrEmpty(string? value, string message = ArgumentNullOrEmpty) => + !string.IsNullOrEmpty(value) ? value : throw new InvalidOperationException(message); - /// - /// Performs a general pre-condition check that fails if the specified value is or a whitespace string. - /// - /// The value to check. - /// The exception message to throw in the event that the specified value is or a whitespace string. - /// Returns a non-null, non-empty value. - /// If the specified value is or a whitespace string. - public static string CheckNotNullOrWhiteSpace(string? value, string message = ArgumentNullOrWhiteSpace) => - !string.IsNullOrWhiteSpace(value) ? value : throw new InvalidOperationException(message); + /// + /// Performs a general pre-condition check that fails if the specified value is or a whitespace string. + /// + /// The value to check. + /// The exception message to throw in the event that the specified value is or a whitespace string. + /// Returns a non-null, non-empty value. + /// If the specified value is or a whitespace string. + public static string CheckNotNullOrWhiteSpace(string? value, string message = ArgumentNullOrWhiteSpace) => + !string.IsNullOrWhiteSpace(value) ? value : throw new InvalidOperationException(message); + } /// - /// Performs a general pre-condition requirement that fails when the specified condition is . + /// Provides with static extension methods for performing pre-conditions and guard clauses. /// - /// The condition to check. - /// The exception message to throw in the event that the specified condition is . - /// The name of the invalid parameter. - /// If the specified condition is . - public static void Require(bool condition, string message = ArgumentFailed, string? parameterName = null) + extension(ArgumentException) { - if (!condition) throw new ArgumentException(message, parameterName); - } + /// + /// Performs a general pre-condition requirement that fails when the specified condition is . + /// + /// The condition to check. + /// The exception message to throw in the event that the specified condition is . + /// The name of the invalid parameter. + /// If the specified condition is . + public static void Require(bool condition, string message = ArgumentFailed, string? parameterName = null) + { + if (!condition) throw new ArgumentException(message, parameterName); + } - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// Returns the current as a instance. - /// If the specified is not of type . - public static Failure RequireIsFailure(Result result, string message = ArgumentIsNotFailure) => - result as Failure ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Failure RequireIsFailure( + Result result, + string message = ArgumentIsNotFailure, + [CallerArgumentExpression(nameof(result))] + string? parameterName = null + ) => result as Failure ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// Returns the current as a instance. - /// If the specified is not of type . - public static Success RequireIsSuccess(Result result, string message = ArgumentIsNotSuccess) => - result as Success ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Success RequireIsSuccess( + Result result, + string message = ArgumentIsNotSuccess, + [CallerArgumentExpression(nameof(result))] + string? parameterName = null + ) => result as Success ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Failure RequireIsFailure(Result result, string message = ArgumentIsNotFailure) => - result as Failure ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Failure RequireIsFailure( + Result result, + string message = ArgumentIsNotFailure, + [CallerArgumentExpression(nameof(result))] + string? parameterName = null + ) => result as Failure ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Success RequireIsSuccess(Result result, string message = ArgumentIsNotSuccess) => - result as Success ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Success RequireIsSuccess( + Result result, + string message = ArgumentIsNotSuccess, + [CallerArgumentExpression(nameof(result))] + string? parameterName = null + ) => result as Success ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static None RequireIsNone(Optional optional, string message = ArgumentIsNotNone) where T : notnull => - optional as None ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static None RequireIsNone( + Optional optional, + string message = ArgumentIsNotNone, + [CallerArgumentExpression(nameof(optional))] + string? parameterName = null + ) where T : notnull => optional as None ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition check that fails when the specified is not of type . - /// - /// The current to check. - /// The exception message to throw in the event that the specified is not of type . - /// The underlying type of the current instance. - /// Returns the current as a instance. - /// If the specified is not of type . - public static Some RequireIsSome(Optional optional, string message = ArgumentIsNotSome) where T : notnull => - optional as Some ?? throw new ArgumentException(message); + /// + /// Performs a general pre-condition check that fails when the specified is not of type . + /// + /// The current to check. + /// The exception message to throw in the event that the specified is not of type . + /// The name of the invalid parameter. + /// The underlying type of the current instance. + /// Returns the current as a instance. + /// If the specified is not of type . + public static Some RequireIsSome( + Optional optional, + string message = ArgumentIsNotSome, + [CallerArgumentExpression(nameof(optional))] + string? parameterName = null + ) where T : notnull => optional as Some ?? throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition requirement that fails when the specified value falls inclusively outside the specified minimum and maximum values. - /// - /// The value to check. - /// The inclusive minimum value to test. - /// The inclusive maximum value to test. - /// The exception message to throw in the event that the specified value falls inclusively outside the specified minimum and maximum values. - /// The name of the invalid parameter. - /// The underlying type of the value to check. - /// If the specified value falls inclusively outside the specified minimum and maximum values. - public static T RequireWithinRangeInclusive(T value, T min, T max, string message = ArgumentOutOfRange, string? parameterName = null) where T : IComparable => - value.IsWithinRangeInclusive(min, max) ? value : throw new ArgumentOutOfRangeException(parameterName, message); + /// + /// Performs a general pre-condition requirement that fails if the specified value is or an empty string. + /// + /// The value to check. + /// The exception message to throw in the event that the specified value is or an empty string. + /// The name of the invalid parameter. + /// Returns a non-null, non-empty value. + /// If the specified value is or an empty string. + public static string RequireNotNullOrEmpty( + [NotNull] string? value, + string message = ArgumentNullOrEmpty, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) => !string.IsNullOrEmpty(value) ? value : throw new ArgumentException(message, parameterName); - /// - /// Performs a general pre-condition requirement that fails when the specified value falls exclusively outside the specified minimum and maximum values. - /// - /// The value to check. - /// The exclusive minimum value to test. - /// The exclusive maximum value to test. - /// The exception message to throw in the event that the specified value falls exclusively outside the specified minimum and maximum values. - /// The name of the invalid parameter. - /// The underlying type of the value to check. - /// If the specified value falls exclusively outside the specified minimum and maximum values. - public static T RequireWithinRangeExclusive(T value, T min, T max, string message = ArgumentOutOfRange, string? parameterName = null) where T : IComparable => - value.IsWithinRangeExclusive(min, max) ? value : throw new ArgumentOutOfRangeException(parameterName, message); + /// + /// Performs a general pre-condition requirement that fails if the specified value is or a whitespace string. + /// + /// The value to check. + /// The exception message to throw in the event that the specified value is or a whitespace string. + /// The name of the invalid parameter. + /// Returns a non-null, non-empty value. + /// If the specified value is or a whitespace string. + public static string RequireNotNullOrWhiteSpace( + [NotNull] string? value, + string message = ArgumentNullOrWhiteSpace, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) => !string.IsNullOrWhiteSpace(value) ? value : throw new ArgumentException(message, parameterName); + } /// - /// Performs a general pre-condition requirement that fails if the specified value is . + /// Provides with static extension methods for performing pre-conditions and guard clauses. /// - /// The nullable value to check. - /// The exception message to throw in the event that the specified value is . - /// The name of the invalid parameter. - /// The underlying type of the value. - /// Returns a non-null value of the specified type. - /// If the specified value is . - public static T RequireNotNull(T? value, string message = ArgumentNull, string? parameterName = null) => - value ?? throw new ArgumentNullException(parameterName, message); + extension(ArgumentNullException) + { + /// + /// Performs a general pre-condition requirement that fails if the specified value is . + /// + /// The nullable value to check. + /// The exception message to throw in the event that the specified value is . + /// The name of the invalid parameter. + /// The underlying type of the value. + /// Returns a non-null value of the specified type. + /// If the specified value is . + public static T RequireNotNull( + [NotNull] T? value, + string message = ArgumentNull, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) => value ?? throw new ArgumentNullException(parameterName, message); - /// - /// Performs a general pre-condition requirement that fails if the specified value is . - /// - /// The nullable value to check. - /// The exception message to throw in the event that the specified value is . - /// The name of the invalid parameter. - /// The underlying type of the value. - /// Returns a non-null value of the specified type. - /// If the specified value is . - public static T RequireNotNull(T? value, string message = ArgumentNull, string? parameterName = null) where T : struct => - value ?? throw new ArgumentNullException(parameterName, message); + /// + /// Performs a general pre-condition requirement that fails if the specified value is . + /// + /// The nullable value to check. + /// The exception message to throw in the event that the specified value is . + /// The name of the invalid parameter. + /// The underlying type of the value. + /// Returns a non-null value of the specified type. + /// If the specified value is . + public static T RequireNotNull( + [NotNull] T? value, + string message = ArgumentNull, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) where T : struct => value ?? throw new ArgumentNullException(parameterName, message); + } /// - /// Performs a general pre-condition requirement that fails if the specified value is or an empty string. + /// Provides with static extension methods for performing pre-conditions and guard clauses. /// - /// The value to check. - /// The exception message to throw in the event that the specified value is or an empty string. - /// The name of the invalid parameter. - /// Returns a non-null, non-empty value. - /// If the specified value is or an empty string. - public static string RequireNotNullOrEmpty(string? value, string message = ArgumentNullOrEmpty, string? parameterName = null) => - !string.IsNullOrEmpty(value) ? value : throw new ArgumentException(message, parameterName); + extension(ArgumentOutOfRangeException) + { + /// + /// Performs a general pre-condition requirement that fails when the specified value falls inclusively outside the specified minimum and maximum values. + /// + /// The value to check. + /// The inclusive minimum value to test. + /// The inclusive maximum value to test. + /// The exception message to throw in the event that the specified value falls inclusively outside the specified minimum and maximum values. + /// The name of the invalid parameter. + /// The underlying type of the value to check. + /// If the specified value falls inclusively outside the specified minimum and maximum values. + public static T RequireWithinRangeInclusive( + T value, + T minimum, + T maximum, + string message = ArgumentOutOfRange, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) where T : IComparable => value.IsWithinRangeInclusive(minimum, maximum) + ? value + : throw new ArgumentOutOfRangeException(parameterName, message); - /// - /// Performs a general pre-condition requirement that fails if the specified value is or a whitespace string. - /// - /// The value to check. - /// The exception message to throw in the event that the specified value is or a whitespace string. - /// The name of the invalid parameter. - /// Returns a non-null, non-empty value. - /// If the specified value is or a whitespace string. - public static string RequireNotNullOrWhiteSpace(string? value, string message = ArgumentNullOrWhiteSpace, string? parameterName = null) => - !string.IsNullOrWhiteSpace(value) ? value : throw new ArgumentException(message, parameterName); + /// + /// Performs a general pre-condition requirement that fails when the specified value falls exclusively outside the specified minimum and maximum values. + /// + /// The value to check. + /// The exclusive minimum value to test. + /// The exclusive maximum value to test. + /// The exception message to throw in the event that the specified value falls exclusively outside the specified minimum and maximum values. + /// The name of the invalid parameter. + /// The underlying type of the value to check. + /// If the specified value falls exclusively outside the specified minimum and maximum values. + public static T RequireWithinRangeExclusive( + T value, + T minimum, + T maximum, + string message = ArgumentOutOfRange, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) where T : IComparable => value.IsWithinRangeExclusive(minimum, maximum) + ? value + : throw new ArgumentOutOfRangeException(parameterName, message); - /// - /// Performs a general pre-condition requirement that the specified value is defined by the specified type. - /// - /// The enum value to check. - /// The name of the invalid parameter. - /// The underlying type of the . - /// If the specified value is not defined by the specified type. - public static T RequireIsDefined(T value, string? parameterName = null) where T : struct, Enum => - Enum.IsDefined(value) ? value : throw new ArgumentOutOfRangeException(parameterName, $"Invalid {typeof(T).Name} enum value: {value}. Valid values include: {Enum.GetNames().JoinToString()}."); + /// + /// Performs a general pre-condition requirement that the specified value is defined by the specified type. + /// + /// The enum value to check. + /// The name of the invalid parameter. + /// The underlying type of the . + /// If the specified value is not defined by the specified type. + public static T RequireIsDefined( + T value, + [CallerArgumentExpression(nameof(value))] + string? parameterName = null + ) where T : struct, Enum => Enum.IsDefined(value) + ? value + : throw new ArgumentOutOfRangeException(parameterName, $"Invalid {typeof(T).Name} enum value: {value}. Valid values include: {Enum.GetNames().JoinToString()}."); + } } diff --git a/OnixLabs.Core/Reflection/CSharpTypeDeclarationFormatter.cs b/OnixLabs.Core/Reflection/CSharpTypeDeclarationFormatter.cs index 623b88c..57d0d2d 100644 --- a/OnixLabs.Core/Reflection/CSharpTypeDeclarationFormatter.cs +++ b/OnixLabs.Core/Reflection/CSharpTypeDeclarationFormatter.cs @@ -73,7 +73,7 @@ internal static class CSharpTypeDeclarationFormatter /// Returns the type declaration for the current instance. public static string GetTypeDeclaration(Type type, TypeDeclarationFlags flags) { - RequireNotNull(type, TypeNullExceptionMessage, nameof(type)); + RequireNotNull(type, TypeNullExceptionMessage); Type unwrappedType = ConditionallyUnwrapNullableType(type, flags); StringBuilder builder = new(); diff --git a/OnixLabs.Core/Specification.cs b/OnixLabs.Core/Specification.cs index 05a969f..ef42165 100644 --- a/OnixLabs.Core/Specification.cs +++ b/OnixLabs.Core/Specification.cs @@ -24,7 +24,7 @@ namespace OnixLabs.Core; /// Represents the base class for implementing composable specifications using logical operations. /// /// The underlying type of the subject to which the specification applies. -// ReSharper disable PossibleMultipleEnumeration +// ReSharper disable PossibleMultipleEnumeration MemberCanBePrivate.Global public abstract class Specification { /// diff --git a/OnixLabs.Core/Text/Base16.Convertible.cs b/OnixLabs.Core/Text/Base16.Convertible.cs index 34873de..e6b84ec 100644 --- a/OnixLabs.Core/Text/Base16.Convertible.cs +++ b/OnixLabs.Core/Text/Base16.Convertible.cs @@ -21,22 +21,22 @@ namespace OnixLabs.Core.Text; public readonly partial struct Base16 { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base16(byte[] value) => new(value); /// @@ -62,11 +62,11 @@ public readonly partial struct Base16 public static implicit operator Base16(string value) => new(value); /// - /// Create a new instance from the specified value. - /// The value will be encoded using the encoding. + /// Create a new instance from the specified array. + /// The array will be encoded using the encoding. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base16(char[] value) => new(value); /// diff --git a/OnixLabs.Core/Text/Base16.cs b/OnixLabs.Core/Text/Base16.cs index a083964..f746e98 100644 --- a/OnixLabs.Core/Text/Base16.cs +++ b/OnixLabs.Core/Text/Base16.cs @@ -24,6 +24,8 @@ namespace OnixLabs.Core.Text; /// The with which to initialize the instance. public readonly partial struct Base16(ReadOnlySpan value) : IBaseValue { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -44,7 +46,7 @@ public Base16(string value, Encoding? encoding = null) : this(encoding.GetOrDefa /// /// Initializes a new instance of the struct. /// - /// The with which to initialize the instance. + /// The array with which to initialize the instance. /// The which will be used to obtain the underlying value. // ReSharper disable once MemberCanBePrivate.Global public Base16(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) @@ -60,6 +62,4 @@ public Base16(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefa public Base16(ReadOnlySequence value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) { } - - private readonly byte[] value = value.ToArray(); } diff --git a/OnixLabs.Core/Text/Base16Codec.cs b/OnixLabs.Core/Text/Base16Codec.cs index b32af14..c751500 100644 --- a/OnixLabs.Core/Text/Base16Codec.cs +++ b/OnixLabs.Core/Text/Base16Codec.cs @@ -20,10 +20,10 @@ namespace OnixLabs.Core.Text; /// /// Represents a codec for encoding and decoding Base-16 values. /// +// ReSharper disable StringLiteralTypo public sealed class Base16Codec : IBaseCodec { private static readonly SearchValues Base16UppercaseValues = SearchValues.Create("ABCDEF"); - private static readonly SearchValues Base16LowercaseValues = SearchValues.Create("abcdef"); /// @@ -39,11 +39,11 @@ public string Encode(ReadOnlySpan value, IFormatProvider? provider = null) } /// - /// Decodes the specified Base-16 representation into a . + /// Decodes the specified Base-16 representation into a array. /// - /// The Base-16 value to decode into a . + /// The Base-16 value to decode into a array. /// The format provider that will be used to decode the specified value. - /// Returns a new decoded from the specified value. + /// Returns a new array decoded from the specified value. public byte[] Decode(ReadOnlySpan value, IFormatProvider? provider = null) { if (TryDecode(value, provider, out byte[] result)) return result; @@ -90,13 +90,13 @@ public bool TryEncode(ReadOnlySpan value, IFormatProvider? provider, out s } /// - /// Tries to decode the specified Base-16 representation into a . + /// Tries to decode the specified Base-16 representation into a array. /// - /// The Base-16 value to decode into a . + /// The Base-16 value to decode into a array. /// The format provider that will be used to decode the specified value. /// - /// A new decoded from the specified value, - /// or an empty if the specified value could not be decoded. + /// A new array decoded from the specified value, + /// or an empty array if the specified value could not be decoded. /// /// Returns if the specified value was decoded successfully; otherwise, . public bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out byte[] result) diff --git a/OnixLabs.Core/Text/Base16FormatProvider.cs b/OnixLabs.Core/Text/Base16FormatProvider.cs index 2d677f0..cb0f3e1 100644 --- a/OnixLabs.Core/Text/Base16FormatProvider.cs +++ b/OnixLabs.Core/Text/Base16FormatProvider.cs @@ -19,12 +19,12 @@ namespace OnixLabs.Core.Text; /// /// Represents a Base-16 format provider. /// -// ReSharper disable HeapView.ObjectAllocation.Evident +// ReSharper disable HeapView.ObjectAllocation.Evident StringLiteralTypo public sealed class Base16FormatProvider : Enumeration, IFormatProvider { /// /// Gets the invariant Base-16 format provider. - /// The invariant format provider favours lowercase for Base-16 encoding. + /// The invariant format provider favors lowercase for Base-16 encoding. /// The alphabet provided by this format provider is not a strict Base-16 alphabet as it contains all uppercase and lowercase values. /// public static readonly Base16FormatProvider Invariant = new(0, nameof(Invariant), "0123456789ABCDEFabcdef"); diff --git a/OnixLabs.Core/Text/Base32.Convertible.cs b/OnixLabs.Core/Text/Base32.Convertible.cs index 3b65a27..5aa829b 100644 --- a/OnixLabs.Core/Text/Base32.Convertible.cs +++ b/OnixLabs.Core/Text/Base32.Convertible.cs @@ -21,22 +21,22 @@ namespace OnixLabs.Core.Text; public readonly partial struct Base32 { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base32(byte[] value) => new(value); /// @@ -62,11 +62,11 @@ public readonly partial struct Base32 public static implicit operator Base32(string value) => new(value); /// - /// Create a new instance from the specified value. - /// The value will be encoded using the encoding. + /// Create a new instance from the specified array. + /// The array will be encoded using the encoding. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base32(char[] value) => new(value); /// diff --git a/OnixLabs.Core/Text/Base32.cs b/OnixLabs.Core/Text/Base32.cs index bd21b60..db77b7d 100644 --- a/OnixLabs.Core/Text/Base32.cs +++ b/OnixLabs.Core/Text/Base32.cs @@ -24,6 +24,8 @@ namespace OnixLabs.Core.Text; /// The with which to initialize the instance. public readonly partial struct Base32(ReadOnlySpan value) : IBaseValue { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -44,7 +46,7 @@ public Base32(string value, Encoding? encoding = null) : this(encoding.GetOrDefa /// /// Initializes a new instance of the struct. /// - /// The with which to initialize the instance. + /// The array with which to initialize the instance. /// The which will be used to obtain the underlying value. // ReSharper disable once MemberCanBePrivate.Global public Base32(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) @@ -60,6 +62,4 @@ public Base32(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefa public Base32(ReadOnlySequence value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) { } - - private readonly byte[] value = value.ToArray(); } diff --git a/OnixLabs.Core/Text/Base32Codec.cs b/OnixLabs.Core/Text/Base32Codec.cs index b287bac..624539f 100644 --- a/OnixLabs.Core/Text/Base32Codec.cs +++ b/OnixLabs.Core/Text/Base32Codec.cs @@ -45,11 +45,11 @@ public string Encode(ReadOnlySpan value, IFormatProvider? provider = null) } /// - /// Decodes the specified Base-32 representation into a . + /// Decodes the specified Base-32 representation into a array. /// - /// The Base-32 value to decode into a . + /// The Base-32 value to decode into a array. /// The format provider that will be used to decode the specified value. - /// Returns a new decoded from the specified value. + /// Returns a new array decoded from the specified value. public byte[] Decode(ReadOnlySpan value, IFormatProvider? provider = null) { if (TryDecode(value, provider, out byte[] result)) return result; @@ -136,13 +136,13 @@ public bool TryEncode(ReadOnlySpan value, IFormatProvider? provider, out s } /// - /// Tries to decode the specified Base-32 representation into a . + /// Tries to decode the specified Base-32 representation into a array. /// - /// The Base-32 value to decode into a . + /// The Base-32 value to decode into a array. /// The format provider that will be used to decode the specified value. /// - /// A new decoded from the specified value, - /// or an empty if the specified value could not be decoded. + /// A new array decoded from the specified value, + /// or an empty array if the specified value could not be decoded. /// /// Returns if the specified value was decoded successfully; otherwise, . public bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out byte[] result) diff --git a/OnixLabs.Core/Text/Base58.Convertible.cs b/OnixLabs.Core/Text/Base58.Convertible.cs index c7ae568..79eacae 100644 --- a/OnixLabs.Core/Text/Base58.Convertible.cs +++ b/OnixLabs.Core/Text/Base58.Convertible.cs @@ -21,22 +21,22 @@ namespace OnixLabs.Core.Text; public readonly partial struct Base58 { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base58(byte[] value) => new(value); /// @@ -62,11 +62,11 @@ public readonly partial struct Base58 public static implicit operator Base58(string value) => new(value); /// - /// Create a new instance from the specified value. - /// The value will be encoded using the encoding. + /// Create a new instance from the specified array. + /// The array will be encoded using the encoding. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base58(char[] value) => new(value); /// diff --git a/OnixLabs.Core/Text/Base58.cs b/OnixLabs.Core/Text/Base58.cs index 2825d0e..142a251 100644 --- a/OnixLabs.Core/Text/Base58.cs +++ b/OnixLabs.Core/Text/Base58.cs @@ -24,6 +24,8 @@ namespace OnixLabs.Core.Text; /// The with which to initialize the instance. public readonly partial struct Base58(ReadOnlySpan value) : IBaseValue { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -44,7 +46,7 @@ public Base58(string value, Encoding? encoding = null) : this(encoding.GetOrDefa /// /// Initializes a new instance of the struct. /// - /// The with which to initialize the instance. + /// The array with which to initialize the instance. /// The which will be used to obtain the underlying value. // ReSharper disable once MemberCanBePrivate.Global public Base58(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) @@ -60,6 +62,4 @@ public Base58(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefa public Base58(ReadOnlySequence value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) { } - - private readonly byte[] value = value.ToArray(); } diff --git a/OnixLabs.Core/Text/Base58Codec.cs b/OnixLabs.Core/Text/Base58Codec.cs index 909c651..c8ea8f0 100644 --- a/OnixLabs.Core/Text/Base58Codec.cs +++ b/OnixLabs.Core/Text/Base58Codec.cs @@ -38,11 +38,11 @@ public string Encode(ReadOnlySpan value, IFormatProvider? provider = null) } /// - /// Decodes the specified Base-58 representation into a . + /// Decodes the specified Base-58 representation into a array. /// - /// The Base-58 value to decode into a . + /// The Base-58 value to decode into a array. /// The format provider that will be used to decode the specified value. - /// Returns a new decoded from the specified value. + /// Returns a new array decoded from the specified value. public byte[] Decode(ReadOnlySpan value, IFormatProvider? provider = null) { if (TryDecode(value, provider, out byte[] result)) return result; @@ -103,13 +103,13 @@ public bool TryEncode(ReadOnlySpan value, IFormatProvider? provider, out s } /// - /// Tries to decode the specified Base-58 representation into a . + /// Tries to decode the specified Base-58 representation into a array. /// - /// The Base-58 value to decode into a . + /// The Base-58 value to decode into a array. /// The format provider that will be used to decode the specified value. /// - /// A new decoded from the specified value, - /// or an empty if the specified value could not be decoded. + /// A new array decoded from the specified value, + /// or an empty array if the specified value could not be decoded. /// /// Returns if the specified value was decoded successfully; otherwise, . public bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out byte[] result) @@ -153,6 +153,7 @@ public bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out b IEnumerable bytesWithoutLeadingZeros = data .ToByteArray() + .AsEnumerable() .Reverse() .SkipWhile(byteValue => byteValue == 0); diff --git a/OnixLabs.Core/Text/Base58FormatProvider.cs b/OnixLabs.Core/Text/Base58FormatProvider.cs index b38ceb0..be496e0 100644 --- a/OnixLabs.Core/Text/Base58FormatProvider.cs +++ b/OnixLabs.Core/Text/Base58FormatProvider.cs @@ -19,7 +19,7 @@ namespace OnixLabs.Core.Text; /// /// Represents a Base-58 format provider. /// -// ReSharper disable HeapView.ObjectAllocation.Evident +// ReSharper disable HeapView.ObjectAllocation.Evident CommentTypo StringLiteralTypo public sealed class Base58FormatProvider : Enumeration, IFormatProvider { /// diff --git a/OnixLabs.Core/Text/Base64.Convertible.cs b/OnixLabs.Core/Text/Base64.Convertible.cs index 44784ff..6b3e088 100644 --- a/OnixLabs.Core/Text/Base64.Convertible.cs +++ b/OnixLabs.Core/Text/Base64.Convertible.cs @@ -21,15 +21,15 @@ namespace OnixLabs.Core.Text; public readonly partial struct Base64 { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// @@ -62,11 +62,11 @@ public readonly partial struct Base64 public static implicit operator Base64(string value) => new(value); /// - /// Create a new instance from the specified value. - /// The value will be encoded using the encoding. + /// Create a new instance from the specified array. + /// The array will be encoded using the encoding. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator Base64(char[] value) => new(value); /// diff --git a/OnixLabs.Core/Text/Base64.cs b/OnixLabs.Core/Text/Base64.cs index 916cda2..99a04f0 100644 --- a/OnixLabs.Core/Text/Base64.cs +++ b/OnixLabs.Core/Text/Base64.cs @@ -24,6 +24,8 @@ namespace OnixLabs.Core.Text; /// The with which to initialize the instance. public readonly partial struct Base64(ReadOnlySpan value) : IBaseValue { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -44,7 +46,7 @@ public Base64(string value, Encoding? encoding = null) : this(encoding.GetOrDefa /// /// Initializes a new instance of the struct. /// - /// The with which to initialize the instance. + /// The array with which to initialize the instance. /// The which will be used to obtain the underlying value. // ReSharper disable once MemberCanBePrivate.Global public Base64(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) @@ -60,6 +62,4 @@ public Base64(char[] value, Encoding? encoding = null) : this(encoding.GetOrDefa public Base64(ReadOnlySequence value, Encoding? encoding = null) : this(encoding.GetOrDefault().GetBytes(value)) { } - - private readonly byte[] value = value.ToArray(); } diff --git a/OnixLabs.Core/Text/Base64Codec.cs b/OnixLabs.Core/Text/Base64Codec.cs index afd447f..7319093 100644 --- a/OnixLabs.Core/Text/Base64Codec.cs +++ b/OnixLabs.Core/Text/Base64Codec.cs @@ -34,11 +34,11 @@ public string Encode(ReadOnlySpan value, IFormatProvider? provider = null) } /// - /// Decodes the specified Base-64 representation into a . + /// Decodes the specified Base-64 representation into a array. /// - /// The Base-64 value to decode into a . + /// The Base-64 value to decode into a array. /// The format provider that will be used to decode the specified value. - /// Returns a new decoded from the specified value. + /// Returns a new array decoded from the specified value. public byte[] Decode(ReadOnlySpan value, IFormatProvider? provider = null) { if (TryDecode(value, provider, out byte[] result)) return result; @@ -82,13 +82,13 @@ public bool TryEncode(ReadOnlySpan value, IFormatProvider? provider, out s } /// - /// Tries to decode the specified Base-64 representation into a . + /// Tries to decode the specified Base-64 representation into a array. /// - /// The Base-64 value to decode into a . + /// The Base-64 value to decode into a array. /// The format provider that will be used to decode the specified value. /// - /// A new decoded from the specified value, - /// or an empty if the specified value could not be decoded. + /// A new array decoded from the specified value, + /// or an empty array if the specified value could not be decoded. /// /// Returns if the specified value was decoded successfully; otherwise, . public bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out byte[] result) diff --git a/OnixLabs.Core/Text/Base64FormatProvider.cs b/OnixLabs.Core/Text/Base64FormatProvider.cs index c5d8bb0..473ff8b 100644 --- a/OnixLabs.Core/Text/Base64FormatProvider.cs +++ b/OnixLabs.Core/Text/Base64FormatProvider.cs @@ -19,7 +19,7 @@ namespace OnixLabs.Core.Text; /// /// Represents a Base-64 format provider. /// -// ReSharper disable HeapView.ObjectAllocation.Evident +// ReSharper disable HeapView.ObjectAllocation.Evident StringLiteralTypo public sealed class Base64FormatProvider : Enumeration, IFormatProvider { /// @@ -33,10 +33,7 @@ public sealed class Base64FormatProvider : Enumeration, IF /// The value of the enumeration entry. /// The name of the enumeration entry. /// The alphabet of the format provider. - private Base64FormatProvider(int value, string name, string alphabet) : base(value, name) - { - Alphabet = alphabet; - } + private Base64FormatProvider(int value, string name, string alphabet) : base(value, name) => Alphabet = alphabet; /// /// Gets the alphabet of the current instance. diff --git a/OnixLabs.Core/Text/Extensions.Encoding.cs b/OnixLabs.Core/Text/Extensions.Encoding.cs index 6286f5a..d8d18a1 100644 --- a/OnixLabs.Core/Text/Extensions.Encoding.cs +++ b/OnixLabs.Core/Text/Extensions.Encoding.cs @@ -23,15 +23,11 @@ namespace OnixLabs.Core.Text; [EditorBrowsable(EditorBrowsableState.Never)] internal static class EncodingExtensions { - /// - /// The default encoding, which is . - /// - private static readonly Encoding Default = Encoding.UTF8; - /// /// Gets the current , or the default encoding if the current is . /// + /// The default encoding is . /// The current . /// Returns the current , or the default encoding if the current is . - public static Encoding GetOrDefault(this Encoding? encoding) => encoding ?? Default; + public static Encoding GetOrDefault(this Encoding? encoding) => encoding ?? Encoding.UTF8; } diff --git a/OnixLabs.Core/Text/Extensions.StringBuilder.cs b/OnixLabs.Core/Text/Extensions.StringBuilder.cs index c4b351b..c140920 100644 --- a/OnixLabs.Core/Text/Extensions.StringBuilder.cs +++ b/OnixLabs.Core/Text/Extensions.StringBuilder.cs @@ -18,7 +18,7 @@ namespace OnixLabs.Core.Text; /// -/// Provides extension methods for string builders. +/// Provides extension methods for instances. /// // ReSharper disable UnusedMethodReturnValue.Global [EditorBrowsable(EditorBrowsableState.Never)] @@ -29,152 +29,151 @@ public static class StringBuilderExtensions /// /// Appends the specified values to the current . /// - /// The to append to. /// The values to append. + /// The current instance. /// Returns the current with the specified values appended. - public static StringBuilder Append(this StringBuilder builder, params object[] values) => builder.AppendJoin(string.Empty, values); + public static StringBuilder Append(this StringBuilder receiver, params object[] values) => receiver.AppendJoin(string.Empty, values); /// /// Appends the specified value, prefixed with the escape sequence to the current . /// - /// The to append to. /// The value to append. + /// The current instance. /// Returns the current with the escape sequence and specified value appended. - internal static StringBuilder AppendEscaped(this StringBuilder builder, char value) => builder.Append(EscapeSequence).Append(value); + internal static StringBuilder AppendEscaped(this StringBuilder receiver, char value) => receiver.Append(EscapeSequence).Append(value); /// /// Prepends the specified value to the current /// - /// The to prepend to. /// The value to prepend. + /// The current instance. /// Returns the current with the specified values prepended. - public static StringBuilder Prepend(this StringBuilder builder, object value) => builder.Insert(0, value); + public static StringBuilder Prepend(this StringBuilder receiver, object value) => receiver.Insert(0, value); /// /// Prepends the specified value to the current /// - /// The to prepend to. /// The value to prepend. + /// The current instance. /// Returns the current with the specified values prepended. - public static StringBuilder Prepend(this StringBuilder builder, char value) => builder.Insert(0, value); + public static StringBuilder Prepend(this StringBuilder receiver, char value) => receiver.Insert(0, value); /// /// Prepends the specified value to the current /// - /// The to prepend to. /// The value to prepend. + /// The current instance. /// Returns the current with the specified values prepended. - public static StringBuilder Prepend(this StringBuilder builder, string value) => builder.Insert(0, value); + public static StringBuilder Prepend(this StringBuilder receiver, string value) => receiver.Insert(0, value); /// /// Prepends the specified values to the current . /// - /// The to prepend to. /// The values to prepend. + /// The current instance. /// Returns the current with the specified values prepended. - public static StringBuilder Prepend(this StringBuilder builder, params object[] values) => builder.PrependJoin(string.Empty, values); + public static StringBuilder Prepend(this StringBuilder receiver, params object[] values) => receiver.PrependJoin(string.Empty, values); /// /// Concatenates the string representations of the elements in the provided array of objects, using the specified separator between each member, then prepends the result to the current instance of the string builder. /// - /// The to prepend to. /// The string to use as a separator. is included in the joined strings only if has more than one element. /// An array that contains the strings to concatenate and append to the current instance of the string builder. + /// The current instance. /// Returns the current with the specified values joined and prepended. - public static StringBuilder PrependJoin(this StringBuilder builder, string separator, params object?[] values) => - builder.Prepend(string.Join(separator, values)); + public static StringBuilder PrependJoin(this StringBuilder receiver, string separator, params object?[] values) => receiver.Prepend(string.Join(separator, values)); /// /// Trims the specified value from the start and end of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the start and end. - public static StringBuilder Trim(this StringBuilder builder, char value) => builder.TrimStart(value).TrimEnd(value); + public static StringBuilder Trim(this StringBuilder receiver, char value) => receiver.TrimStart(value).TrimEnd(value); /// /// Trims the specified value from the end of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the end. - public static StringBuilder TrimEnd(this StringBuilder builder, char value) + public static StringBuilder TrimEnd(this StringBuilder receiver, char value) { - while (builder.Length > 0 && builder[^1] == value) - builder.Remove(builder.Length - 1, 1); + while (receiver.Length > 0 && receiver[^1] == value) + receiver.Remove(receiver.Length - 1, 1); - return builder; + return receiver; } /// /// Trims the specified value from the start of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the start. - public static StringBuilder TrimStart(this StringBuilder builder, char value) + public static StringBuilder TrimStart(this StringBuilder receiver, char value) { - while (builder.Length > 0 && builder[0] == value) - builder.Remove(0, 1); + while (receiver.Length > 0 && receiver[0] == value) + receiver.Remove(0, 1); - return builder; + return receiver; } /// /// Trims the specified value from the start and end of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the start and end. - public static StringBuilder Trim(this StringBuilder builder, string value) => builder.TrimStart(value).TrimEnd(value); + public static StringBuilder Trim(this StringBuilder receiver, string value) => receiver.TrimStart(value).TrimEnd(value); /// /// Trims the specified value from the end of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the end. - public static StringBuilder TrimEnd(this StringBuilder builder, string value) + public static StringBuilder TrimEnd(this StringBuilder receiver, string value) { - if (string.IsNullOrEmpty(value)) return builder; + if (string.IsNullOrEmpty(value)) return receiver; - while (builder.Length >= value.Length && builder.ToString(builder.Length - value.Length, value.Length) == value) - builder.Remove(builder.Length - value.Length, value.Length); + while (receiver.Length >= value.Length && receiver.ToString(receiver.Length - value.Length, value.Length) == value) + receiver.Remove(receiver.Length - value.Length, value.Length); - return builder; + return receiver; } /// /// Trims the specified value from the start of the current . /// - /// The to trim. /// The value to trim. + /// The current instance. /// Returns the current with the specified value trimmed from the start. - public static StringBuilder TrimStart(this StringBuilder builder, string value) + public static StringBuilder TrimStart(this StringBuilder receiver, string value) { - if (string.IsNullOrEmpty(value)) return builder; + if (string.IsNullOrEmpty(value)) return receiver; - while (builder.Length >= value.Length && builder.ToString(0, value.Length) == value) - builder.Remove(0, value.Length); + while (receiver.Length >= value.Length && receiver.ToString(0, value.Length) == value) + receiver.Remove(0, value.Length); - return builder; + return receiver; } /// /// Wraps the current between the specified start and end values. /// - /// The to wrap. /// The value to prepend. /// The value to append. + /// The current instance. /// Returns the current wrapped between the specified start and end values. - public static StringBuilder Wrap(this StringBuilder builder, char start, char end) => builder.Prepend(start).Append(end); + public static StringBuilder Wrap(this StringBuilder receiver, char start, char end) => receiver.Prepend(start).Append(end); /// /// Wraps the current between the specified start and end values. /// - /// The to wrap. /// The value to prepend. /// The value to append. + /// The current instance. /// Returns the current wrapped between the specified start and end values. - public static StringBuilder Wrap(this StringBuilder builder, string start, string end) => builder.Prepend(start).Append(end); + public static StringBuilder Wrap(this StringBuilder receiver, string start, string end) => receiver.Prepend(start).Append(end); } diff --git a/OnixLabs.Core/Text/Extensions.cs b/OnixLabs.Core/Text/Extensions.cs index d4fb287..7d32c9b 100644 --- a/OnixLabs.Core/Text/Extensions.cs +++ b/OnixLabs.Core/Text/Extensions.cs @@ -18,65 +18,40 @@ namespace OnixLabs.Core.Text; /// -/// Provides extension methods for byte arrays and read-only spans. +/// Provides extension methods instances. /// // ReSharper disable UnusedMethodReturnValue.Global [EditorBrowsable(EditorBrowsableState.Never)] public static class Extensions { /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base16 ToBase16(this byte[] value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base32 ToBase32(this byte[] value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base58 ToBase58(this byte[] value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base64 ToBase64(this byte[] value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base16 ToBase16(this ReadOnlySpan value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base32 ToBase32(this ReadOnlySpan value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base58 ToBase58(this ReadOnlySpan value) => new(value); - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Base64 ToBase64(this ReadOnlySpan value) => new(value); + /// Provides extension methods instances. + /// + /// The current instance. + extension(ReadOnlySpan receiver) + { + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Base16 ToBase16() => new(receiver); + + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Base32 ToBase32() => new(receiver); + + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Base58 ToBase58() => new(receiver); + + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Base64 ToBase64() => new(receiver); + } } diff --git a/OnixLabs.Core/Text/IBaseCodec.cs b/OnixLabs.Core/Text/IBaseCodec.cs index e399345..397f296 100644 --- a/OnixLabs.Core/Text/IBaseCodec.cs +++ b/OnixLabs.Core/Text/IBaseCodec.cs @@ -73,14 +73,14 @@ public static string GetString(ReadOnlySpan value, IFormatProvider provide } /// - /// Obtains a new array by converting the specified value. + /// Obtains a new array array by converting the specified value. /// /// The value to convert. /// /// The which will be used to convert the specified value. /// Allowed values for this parameter are , , , and . /// - /// Returns a new array by converting the specified value. + /// Returns a new array array by converting the specified value. /// If the specified value cannot be converted. public static byte[] GetBytes(ReadOnlySpan value, IFormatProvider provider) { @@ -113,14 +113,14 @@ public static bool TryGetString(ReadOnlySpan value, IFormatProvider provid } /// - /// Tries to obtain a new array by converting the specified value. + /// Tries to obtain a new array array by converting the specified value. /// /// The value to convert. /// /// The which will be used to convert the specified value. /// Allowed values for this parameter are , , , and . /// - /// A new array by converting the specified value, or an empty array if the value cannot be converted. + /// A new array array by converting the specified value, or an empty array array if the value cannot be converted. /// Returns if the conversion was successful; otherwise, . public static bool TryGetBytes(ReadOnlySpan value, IFormatProvider provider, out byte[] result) { @@ -170,11 +170,11 @@ protected static bool TryGetFormatProvider(IFormatProvider? provider, T defau string Encode(ReadOnlySpan value, IFormatProvider? provider = null); /// - /// Decodes the specified Base-N representation into a . + /// Decodes the specified Base-N representation into a array. /// - /// The Base-N value to decode into a . + /// The Base-N value to decode into a array. /// The format provider that will be used to decode the specified value. - /// Returns a new decoded from the specified value. + /// Returns a new array decoded from the specified value. byte[] Decode(ReadOnlySpan value, IFormatProvider? provider = null); /// @@ -190,13 +190,13 @@ protected static bool TryGetFormatProvider(IFormatProvider? provider, T defau bool TryEncode(ReadOnlySpan value, IFormatProvider? provider, out string result); /// - /// Tries to decode the specified Base-N representation into a . + /// Tries to decode the specified Base-N representation into a array. /// - /// The Base-N value to decode into a . + /// The Base-N value to decode into a array. /// The format provider that will be used to decode the specified value. /// - /// A new decoded from the specified value, - /// or an empty if the specified value could not be decoded. + /// A new array decoded from the specified value, + /// or an empty array if the specified value could not be decoded. /// /// Returns if the specified value was decoded successfully; otherwise, . bool TryDecode(ReadOnlySpan value, IFormatProvider? provider, out byte[] result); diff --git a/OnixLabs.DependencyInjection/Extensions.IServiceCollection.cs b/OnixLabs.DependencyInjection/Extensions.IServiceCollection.cs index 832ed58..bc89d33 100644 --- a/OnixLabs.DependencyInjection/Extensions.IServiceCollection.cs +++ b/OnixLabs.DependencyInjection/Extensions.IServiceCollection.cs @@ -19,184 +19,173 @@ namespace OnixLabs.DependencyInjection; /// -/// Provides extension methods for . +/// Provides extension methods for instances. /// -// ReSharper disable InconsistentNaming +// ReSharper disable InconsistentNaming UnusedMethodReturnValue.Global [EditorBrowsable(EditorBrowsableState.Never)] public static class IServiceCollectionExtensions { /// - /// Adds a service of the type specified in to the specified . + /// Provides extension methods for instances. /// - /// The to add the service to. - /// The lifetime of the specified service. The default lifetime is . - /// The underlying type of the service to add. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddService( - this IServiceCollection services, - ServiceLifetime lifetime = default - ) where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch + /// The current instance. + extension(IServiceCollection services) { - ServiceLifetime.Singleton => services.AddSingleton(), - ServiceLifetime.Scoped => services.AddScoped(), - ServiceLifetime.Transient => services.AddTransient(), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a service of the type specified in to the specified . + /// + /// The lifetime of the specified service. The default lifetime is . + /// The underlying type of the service to add. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddService( + ServiceLifetime lifetime = default + ) where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddSingleton(), + ServiceLifetime.Scoped => services.AddScoped(), + ServiceLifetime.Transient => services.AddTransient(), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a keyed service of the type specified in to the specified . - /// - /// The to add the service to. - /// The of the service. - /// The lifetime of the specified service. The default lifetime is . - /// The underlying type of the service to add. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddKeyedService( - this IServiceCollection services, - object? serviceKey, - ServiceLifetime lifetime = default - ) where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey), - ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey), - ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a keyed service of the type specified in to the specified . + /// + /// The of the service. + /// The lifetime of the specified service. The default lifetime is . + /// The underlying type of the service to add. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddKeyedService( + object? serviceKey, + ServiceLifetime lifetime = default + ) where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey), + ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey), + ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a service of the type specified in to the specified . - /// - /// The to add the service to. - /// The factory that creates the service. - /// The lifetime of the specified service. The default lifetime is . - /// The underlying type of the service to add. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddService( - this IServiceCollection services, - Func implementationFactory, - ServiceLifetime lifetime = default - ) where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddSingleton(implementationFactory), - ServiceLifetime.Scoped => services.AddScoped(implementationFactory), - ServiceLifetime.Transient => services.AddTransient(implementationFactory), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a service of the type specified in to the specified . + /// + /// The factory that creates the service. + /// The lifetime of the specified service. The default lifetime is . + /// The underlying type of the service to add. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddService( + Func implementationFactory, + ServiceLifetime lifetime = default + ) where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddSingleton(implementationFactory), + ServiceLifetime.Scoped => services.AddScoped(implementationFactory), + ServiceLifetime.Transient => services.AddTransient(implementationFactory), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds keyed a service of the type specified in to the specified . - /// - /// The to add the service to. - /// The factory that creates the service. - /// The of the service. - /// The lifetime of the specified service. The default lifetime is . - /// The underlying type of the service to add. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddKeyedService( - this IServiceCollection services, - Func implementationFactory, - object? serviceKey, - ServiceLifetime lifetime = default - ) where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey, implementationFactory), - ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey, implementationFactory), - ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey, implementationFactory), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds keyed a service of the type specified in to the specified . + /// + /// The factory that creates the service. + /// The of the service. + /// The lifetime of the specified service. The default lifetime is . + /// The underlying type of the service to add. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddKeyedService( + Func implementationFactory, + object? serviceKey, + ServiceLifetime lifetime = default + ) where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey, implementationFactory), + ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey, implementationFactory), + ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey, implementationFactory), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a service of the type specified in with an implementation type - /// specified in to the specified . - /// - /// The to add the service to. - /// The lifetime of the specified service. The default lifetime is . - /// The type of the service to add. - /// The type of the implementation to use. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddService( - this IServiceCollection services, - ServiceLifetime lifetime = default - ) where TImplementation : class, TService where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddSingleton(), - ServiceLifetime.Scoped => services.AddScoped(), - ServiceLifetime.Transient => services.AddTransient(), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a service of the type specified in with an implementation type + /// specified in to the specified . + /// + /// The lifetime of the specified service. The default lifetime is . + /// The type of the service to add. + /// The type of the implementation to use. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddService( + ServiceLifetime lifetime = default + ) where TImplementation : class, TService where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddSingleton(), + ServiceLifetime.Scoped => services.AddScoped(), + ServiceLifetime.Transient => services.AddTransient(), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a keyed service of the type specified in with an implementation type - /// specified in to the specified . - /// - /// The to add the service to. - /// The of the service. - /// The lifetime of the specified service. The default lifetime is . - /// The type of the service to add. - /// The type of the implementation to use. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddKeyedService( - this IServiceCollection services, - object? serviceKey, - ServiceLifetime lifetime = default - ) where TImplementation : class, TService where TService : class => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey), - ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey), - ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a keyed service of the type specified in with an implementation type + /// specified in to the specified . + /// + /// The of the service. + /// The lifetime of the specified service. The default lifetime is . + /// The type of the service to add. + /// The type of the implementation to use. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddKeyedService(object? serviceKey, + ServiceLifetime lifetime = default + ) where TImplementation : class, TService where TService : class => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceKey), + ServiceLifetime.Scoped => services.AddKeyedScoped(serviceKey), + ServiceLifetime.Transient => services.AddKeyedTransient(serviceKey), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a service of the type specified in with an implementation of the type - /// specified in to the specified . - /// - /// The to add the service to. - /// The type of the service to register. - /// The implementation type of the service. - /// The lifetime of the specified service. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddService( - this IServiceCollection services, - Type serviceType, - Type implementationType, ServiceLifetime lifetime = default - ) => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddSingleton(serviceType, implementationType), - ServiceLifetime.Scoped => services.AddScoped(serviceType, implementationType), - ServiceLifetime.Transient => services.AddTransient(serviceType, implementationType), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a service of the type specified in with an implementation of the type + /// specified in to the specified . + /// + /// The type of the service to register. + /// The implementation type of the service. + /// The lifetime of the specified service. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddService(Type serviceType, + Type implementationType, + ServiceLifetime lifetime = default + ) => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddSingleton(serviceType, implementationType), + ServiceLifetime.Scoped => services.AddScoped(serviceType, implementationType), + ServiceLifetime.Transient => services.AddTransient(serviceType, implementationType), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; - /// - /// Adds a keyed service of the type specified in with an implementation of the type - /// specified in to the specified . - /// - /// The to add the service to. - /// The type of the service to register. - /// The implementation type of the service. - /// The of the service. - /// The lifetime of the specified service. - /// Returns a reference to the current instance after the operation has completed. - /// If the specified is not defined. - public static IServiceCollection AddKeyedService( - this IServiceCollection services, - Type serviceType, - Type implementationType, - object? serviceKey, - ServiceLifetime lifetime = default - ) => RequireIsDefined(lifetime, nameof(lifetime)) switch - { - ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceType, serviceKey, implementationType), - ServiceLifetime.Scoped => services.AddKeyedScoped(serviceType, serviceKey, implementationType), - ServiceLifetime.Transient => services.AddKeyedTransient(serviceType, serviceKey, implementationType), - _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) - }; + /// + /// Adds a keyed service of the type specified in with an implementation of the type + /// specified in to the specified . + /// + /// The type of the service to register. + /// The implementation type of the service. + /// The of the service. + /// The lifetime of the specified service. + /// Returns a reference to the current instance after the operation has completed. + /// If the specified is not defined. + public IServiceCollection AddKeyedService(Type serviceType, + Type implementationType, + object? serviceKey, + ServiceLifetime lifetime = default + ) => RequireIsDefined(lifetime) switch + { + ServiceLifetime.Singleton => services.AddKeyedSingleton(serviceType, serviceKey, implementationType), + ServiceLifetime.Scoped => services.AddKeyedScoped(serviceType, serviceKey, implementationType), + ServiceLifetime.Transient => services.AddKeyedTransient(serviceType, serviceKey, implementationType), + _ => throw new ArgumentOutOfRangeException(nameof(lifetime), lifetime, null) + }; + } } diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAbsDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAbsDataAttribute.cs index ddf48ef..d864c88 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAbsDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAbsDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticAbsDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticAbsDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAdditionDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAdditionDataAttribute.cs index bccf91c..e2428b6 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAdditionDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticAdditionDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticAdditionDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticAdditionDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticDivisionDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticDivisionDataAttribute.cs index 0a083a6..64fa170 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticDivisionDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticDivisionDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticDivisionDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticDivisionDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticModulusDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticModulusDataAttribute.cs index d2de390..c180592 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticModulusDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticModulusDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticModulusDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticModulusDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticMultiplicationDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticMultiplicationDataAttribute.cs index f4b24a2..23e51d1 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticMultiplicationDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticMultiplicationDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticMultiplicationDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticMultiplicationDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticPowDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticPowDataAttribute.cs index d0cd52d..73ce220 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticPowDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticPowDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticPowDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticPowDataAttribute : TestDataAttribute { private static readonly (decimal Value, int Exponent, decimal Expected)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticRoundDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticRoundDataAttribute.cs index 53e70b9..245bd11 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticRoundDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticRoundDataAttribute.cs @@ -12,15 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; using System.Linq; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticRoundDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticRoundDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticScaleDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticScaleDataAttribute.cs index 2addac6..8dd7e48 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticScaleDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticScaleDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticScaleDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticScaleDataAttribute : TestDataAttribute { private static readonly int[] Integers = [0, 1, 2, 3, 123, 123456789, -1, -2, -3, -123, -123456789]; diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticSubtractionDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticSubtractionDataAttribute.cs index 054a4f3..9e02193 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticSubtractionDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticSubtractionDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticSubtractionDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticSubtractionDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTrimDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTrimDataAttribute.cs index 6c3585b..cc79382 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTrimDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTrimDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticTrimDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticTrimDataAttribute : TestDataAttribute { private static readonly (decimal Value, decimal Expected)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTruncateDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTruncateDataAttribute.cs index 882d2c0..0938786 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTruncateDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticTruncateDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticTruncateDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticTruncateDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnaryAdditionDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnaryAdditionDataAttribute.cs index f98652d..b738979 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnaryAdditionDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnaryAdditionDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticUnaryAdditionDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticUnaryAdditionDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnarySubtractionDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnarySubtractionDataAttribute.cs index 72165be..604622c 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnarySubtractionDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalArithmeticUnarySubtractionDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalArithmeticUnarySubtractionDataAttribute : DataAttribute +public sealed class BigDecimalArithmeticUnarySubtractionDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754BinaryDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754BinaryDataAttribute.cs index debb068..d6aa9de 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754BinaryDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754BinaryDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalIeee754BinaryDataAttribute : DataAttribute +public sealed class BigDecimalIeee754BinaryDataAttribute : TestDataAttribute { private static readonly double[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754DecimalDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754DecimalDataAttribute.cs index d28c69b..9e88b92 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754DecimalDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIeee754DecimalDataAttribute.cs @@ -18,7 +18,7 @@ namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalIeee754DecimalDataAttribute : DataAttribute +public sealed class BigDecimalIeee754DecimalDataAttribute : TestDataAttribute { private static readonly (double Value, string Expected)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIsDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIsDataAttribute.cs index 5eeed7a..d8071d9 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalIsDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalIsDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalIsDataAttribute : DataAttribute +public sealed class BigDecimalIsDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/BigDecimalWriteDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/BigDecimalWriteDataAttribute.cs index 73ded2f..ee3fa72 100644 --- a/OnixLabs.Numerics.UnitTests.Data/BigDecimalWriteDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/BigDecimalWriteDataAttribute.cs @@ -12,13 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class BigDecimalWriteDataAttribute : DataAttribute +public sealed class BigDecimalWriteDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/NumberFormatDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumberFormatDataAttribute.cs index 94311a1..1fc69f9 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumberFormatDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumberFormatDataAttribute.cs @@ -12,15 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; using System.Globalization; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumberFormatDataAttribute : DataAttribute +public sealed class NumberFormatDataAttribute : TestDataAttribute { public override IEnumerable GetData(MethodInfo testMethod) { diff --git a/OnixLabs.Numerics.UnitTests.Data/NumberInfoEqualityComparerDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumberInfoEqualityComparerDataAttribute.cs index a14d2ed..8f5552b 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumberInfoEqualityComparerDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumberInfoEqualityComparerDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumberInfoEqualityComparerDataAttribute : DataAttribute +public sealed class NumberInfoEqualityComparerDataAttribute : TestDataAttribute { private static readonly int[] Values = [0, 123456000, -123456000]; private static readonly int[] Scales = [0, 1, 2, 3, 10]; diff --git a/OnixLabs.Numerics.UnitTests.Data/NumberInfoOrdinalityComparerDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumberInfoOrdinalityComparerDataAttribute.cs index 58150a6..3291802 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumberInfoOrdinalityComparerDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumberInfoOrdinalityComparerDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumberInfoOrdinalityComparerDataAttribute : DataAttribute +public sealed class NumberInfoOrdinalityComparerDataAttribute : TestDataAttribute { private static readonly int[] Values = [0, 123456000, -123456000]; private static readonly int[] Scales = [0, 1, 2, 3, 10]; diff --git a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToDecimalDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToDecimalDataAttribute.cs index fb45033..4b4f2e9 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToDecimalDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToDecimalDataAttribute.cs @@ -12,14 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; -using System.Reflection; -using Xunit.Sdk; - namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumericsExtensionsToDecimalDataAttribute : DataAttribute +public sealed class NumericsExtensionsToDecimalDataAttribute : TestDataAttribute { private static readonly (Int128 Value, int Scale, ScaleMode Mode, string Expected)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDecimalDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDecimalDataAttribute.cs index 0deb811..4fc0e9f 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDecimalDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDecimalDataAttribute.cs @@ -12,14 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; using System.Numerics; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumericsExtensionsToNumberInfoDecimalDataAttribute : DataAttribute +public sealed class NumericsExtensionsToNumberInfoDecimalDataAttribute : TestDataAttribute { private static readonly (decimal Value, BigInteger UnscaledValue, int Scale, BigInteger Significand, int Exponent, int Sign, int Precision)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDoubleDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDoubleDataAttribute.cs index 2758ce6..5ac13d1 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDoubleDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoDoubleDataAttribute.cs @@ -12,14 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; using System.Numerics; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumericsExtensionsToNumberInfoDoubleDataAttribute : DataAttribute +public sealed class NumericsExtensionsToNumberInfoDoubleDataAttribute : TestDataAttribute { private static readonly (double Value, BigInteger UnscaledValue, int Scale, BigInteger Significand, int Exponent, int Sign, int Precision)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoFloatDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoFloatDataAttribute.cs index 5224432..1e28740 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoFloatDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoFloatDataAttribute.cs @@ -12,14 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; using System.Numerics; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumericsExtensionsToNumberInfoFloatDataAttribute : DataAttribute +public sealed class NumericsExtensionsToNumberInfoFloatDataAttribute : TestDataAttribute { private static readonly (float Value, BigInteger UnscaledValue, int Scale, BigInteger Significand, int Exponent, int Sign, int Precision)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoIntegerDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoIntegerDataAttribute.cs index eb456d2..60f7a53 100644 --- a/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoIntegerDataAttribute.cs +++ b/OnixLabs.Numerics.UnitTests.Data/NumericsExtensionsToNumberInfoIntegerDataAttribute.cs @@ -12,15 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; -using System.Collections.Generic; using System.Numerics; -using System.Reflection; -using Xunit.Sdk; namespace OnixLabs.Numerics.UnitTests.Data; -public sealed class NumericsExtensionsToNumberInfoIntegerDataAttribute : DataAttribute +public sealed class NumericsExtensionsToNumberInfoIntegerDataAttribute : TestDataAttribute { private static readonly (Int128 Value, BigInteger UnscaledValue, int Scale, BigInteger Significand, int Exponent, int Sign, int Precision)[] Data = [ diff --git a/OnixLabs.Numerics.UnitTests.Data/TestDataAttribute.cs b/OnixLabs.Numerics.UnitTests.Data/TestDataAttribute.cs new file mode 100644 index 0000000..f9509e7 --- /dev/null +++ b/OnixLabs.Numerics.UnitTests.Data/TestDataAttribute.cs @@ -0,0 +1,32 @@ +// Copyright 2020-2025 ONIXLabs +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace OnixLabs.Numerics.UnitTests.Data; + +public abstract class TestDataAttribute : DataAttribute +{ + public abstract IEnumerable GetData(MethodInfo testMethod); + + public override ValueTask> GetData(MethodInfo testMethod, DisposalTracker disposalTracker) + { + List rows = []; + + foreach (object[] objects in GetData(testMethod)) + rows.Add(new TheoryDataRow(objects)); + + return new ValueTask>(rows); + } + + public sealed override bool SupportsDiscoveryEnumeration() => false; +} diff --git a/OnixLabs.Numerics/BigDecimal.Arithmetic.Division.cs b/OnixLabs.Numerics/BigDecimal.Arithmetic.Division.cs index e83938b..e695495 100644 --- a/OnixLabs.Numerics/BigDecimal.Arithmetic.Division.cs +++ b/OnixLabs.Numerics/BigDecimal.Arithmetic.Division.cs @@ -28,7 +28,7 @@ public readonly partial struct BigDecimal /// Returns the quotient of the specified values. public static BigDecimal Divide(BigDecimal left, BigDecimal right, MidpointRounding mode = default) { - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); if (right == Zero) throw new DivideByZeroException(); if (right == One) return left; diff --git a/OnixLabs.Numerics/BigDecimal.Arithmetic.Scale.cs b/OnixLabs.Numerics/BigDecimal.Arithmetic.Scale.cs index 865ae4b..a920e55 100644 --- a/OnixLabs.Numerics/BigDecimal.Arithmetic.Scale.cs +++ b/OnixLabs.Numerics/BigDecimal.Arithmetic.Scale.cs @@ -30,7 +30,7 @@ public readonly partial struct BigDecimal public static BigDecimal SetScale(BigDecimal value, int scale, MidpointRounding mode = default) { Require(scale >= 0, "Scale must be greater than or equal to zero.", nameof(scale)); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); if (scale == value.Scale) return value; if (scale < value.Scale) return Round(value, scale, mode); diff --git a/OnixLabs.Numerics/BigDecimal.cs b/OnixLabs.Numerics/BigDecimal.cs index 77ea6d9..d299aeb 100644 --- a/OnixLabs.Numerics/BigDecimal.cs +++ b/OnixLabs.Numerics/BigDecimal.cs @@ -38,7 +38,7 @@ namespace OnixLabs.Numerics; public BigDecimal(BigInteger value, int scale = 0, ScaleMode mode = default) { Require(scale >= 0, "Scale must be greater than or equal to zero.", nameof(scale)); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); number = value.ToNumberInfo(scale, mode); } @@ -49,7 +49,7 @@ public BigDecimal(BigInteger value, int scale = 0, ScaleMode mode = default) /// The conversion mode that determines whether the floating-point value should be converted from its binary or decimal representation. public BigDecimal(float value, ConversionMode mode = default) { - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); number = value.ToNumberInfo(mode); } @@ -60,7 +60,7 @@ public BigDecimal(float value, ConversionMode mode = default) /// The conversion mode that determines whether the floating-point value should be converted from its binary or decimal representation. public BigDecimal(double value, ConversionMode mode = default) { - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); number = value.ToNumberInfo(mode); } diff --git a/OnixLabs.Numerics/Ieee754Converter.cs b/OnixLabs.Numerics/Ieee754Converter.cs index 2a4a7fd..756657b 100644 --- a/OnixLabs.Numerics/Ieee754Converter.cs +++ b/OnixLabs.Numerics/Ieee754Converter.cs @@ -35,7 +35,7 @@ internal static class Ieee754Converter public static NumberInfo Convert(float value, ConversionMode mode) { RequireRealNumber(value); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); if (IsZeroOrOne(value, out NumberInfo result)) return result; @@ -56,7 +56,7 @@ public static NumberInfo Convert(float value, ConversionMode mode) public static NumberInfo Convert(double value, ConversionMode mode) { RequireRealNumber(value); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); if (IsZeroOrOne(value, out NumberInfo result)) return result; diff --git a/OnixLabs.Numerics/NumericsExtensions.cs b/OnixLabs.Numerics/NumericsExtensions.cs index ccb55b0..c533938 100644 --- a/OnixLabs.Numerics/NumericsExtensions.cs +++ b/OnixLabs.Numerics/NumericsExtensions.cs @@ -71,7 +71,7 @@ public static BigInteger GetUnscaledValue(this decimal value) /// if is negative. public static decimal SetScale(this decimal value, int scale) { - RequireWithinRangeInclusive(scale, 0, MaxScale, "Scale must be within the inclusive range of 0 to 28.", nameof(scale)); + RequireWithinRangeInclusive(scale, 0, MaxScale, "Scale must be within the inclusive range of 0 to 28."); // Determine maximum representable scale given the integer part length BigInteger unscaledValue = value.GetUnscaledValue(); @@ -121,7 +121,7 @@ public static decimal SetScale(this decimal value, int scale) /// if is negative. public static decimal SetScale(this decimal value, int scale, MidpointRounding mode) { - RequireWithinRangeInclusive(scale, 0, MaxScale, "Scale must be within the inclusive range of 0 to 28.", nameof(scale)); + RequireWithinRangeInclusive(scale, 0, MaxScale, "Scale must be within the inclusive range of 0 to 28."); // Determine maximum representable scale BigInteger unscaledValue = value.GetUnscaledValue(); @@ -170,7 +170,7 @@ public static decimal SetScale(this decimal value, int scale, MidpointRounding m private static BigInteger GetUnscaledInteger(this T value, int scale, ScaleMode mode) where T : IBinaryInteger { Require(scale >= 0, "Scale must be greater than or equal to zero.", nameof(value)); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); BigInteger integer = value.ToBigInteger(); return scale == 0 || mode == ScaleMode.Fractional ? integer : integer * BigInteger.Pow(10, scale); @@ -239,7 +239,7 @@ public static BigDecimal ToBigDecimal(this T value, int scale = 0, ScaleMode public static decimal ToDecimal(this T value, int scale = 0, ScaleMode mode = default) where T : IBinaryInteger { Require(scale.IsBetween(0, 28), "Scale must be between 0 and 28."); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); BigInteger scaled = value.GetUnscaledInteger(scale, mode); Check(scaled.IsBetween(MinDecimal, MaxDecimal), $"Value is either too large or too small to convert to {nameof(Decimal)}."); @@ -263,7 +263,7 @@ public static decimal ToDecimal(this T value, int scale = 0, ScaleMode mode = public static NumberInfo ToNumberInfo(this T value, int scale = 0, ScaleMode mode = default) where T : IBinaryInteger { Require(scale >= 0, "Scale must be greater than or equal to zero", nameof(scale)); - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); BigInteger unscaledValue = value.GetUnscaledInteger(scale, mode); return new NumberInfo(unscaledValue, scale); } @@ -276,7 +276,7 @@ public static NumberInfo ToNumberInfo(this T value, int scale = 0, ScaleMode /// Returns a representing the current value. public static NumberInfo ToNumberInfo(this float value, ConversionMode mode = default) { - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); return Ieee754Converter.Convert(value, mode); } @@ -288,7 +288,7 @@ public static NumberInfo ToNumberInfo(this float value, ConversionMode mode = de /// Returns a representing the current value. public static NumberInfo ToNumberInfo(this double value, ConversionMode mode = default) { - RequireIsDefined(mode, nameof(mode)); + RequireIsDefined(mode); return Ieee754Converter.Convert(value, mode); } diff --git a/OnixLabs.Security.Cryptography/DigitalSignature.Convertible.cs b/OnixLabs.Security.Cryptography/DigitalSignature.Convertible.cs index 0b34664..129608a 100644 --- a/OnixLabs.Security.Cryptography/DigitalSignature.Convertible.cs +++ b/OnixLabs.Security.Cryptography/DigitalSignature.Convertible.cs @@ -20,22 +20,22 @@ namespace OnixLabs.Security.Cryptography; public readonly partial struct DigitalSignature { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator DigitalSignature(byte[] value) => new(value); /// diff --git a/OnixLabs.Security.Cryptography/DigitalSignature.cs b/OnixLabs.Security.Cryptography/DigitalSignature.cs index c119792..a1ac7a5 100644 --- a/OnixLabs.Security.Cryptography/DigitalSignature.cs +++ b/OnixLabs.Security.Cryptography/DigitalSignature.cs @@ -24,12 +24,12 @@ namespace OnixLabs.Security.Cryptography; /// The underlying value of the cryptographic digital signature. public readonly partial struct DigitalSignature(ReadOnlySpan value) : ICryptoPrimitive, ISpanParsable { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// /// The with which to initialize the instance. // ReSharper disable once MemberCanBePrivate.Global public DigitalSignature(ReadOnlySequence value) : this(ReadOnlySpan.Empty) => value.CopyTo(out this.value); - - private readonly byte[] value = value.ToArray(); } diff --git a/OnixLabs.Security.Cryptography/DigitalSignatureAndPublicKey.cs b/OnixLabs.Security.Cryptography/DigitalSignatureAndPublicKey.cs index 447d124..4c24139 100644 --- a/OnixLabs.Security.Cryptography/DigitalSignatureAndPublicKey.cs +++ b/OnixLabs.Security.Cryptography/DigitalSignatureAndPublicKey.cs @@ -19,4 +19,5 @@ namespace OnixLabs.Security.Cryptography; /// /// The underlying cryptographic digital signature. /// The underlying named cryptographic public key. +// ReSharper disable UnusedType.Global NotAccessedPositionalProperty.Global public readonly record struct DigitalSignatureAndPublicKey(DigitalSignature Signature, NamedPublicKey Key); diff --git a/OnixLabs.Security.Cryptography/EcdhPrivateKey.Convertible.cs b/OnixLabs.Security.Cryptography/EcdhPrivateKey.Convertible.cs index 3adad3c..8d4add0 100644 --- a/OnixLabs.Security.Cryptography/EcdhPrivateKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/EcdhPrivateKey.Convertible.cs @@ -21,10 +21,10 @@ namespace OnixLabs.Security.Cryptography; public sealed partial class EcdhPrivateKey { /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator EcdhPrivateKey(byte[] value) => new(value); /// diff --git a/OnixLabs.Security.Cryptography/EcdhPrivateKey.Export.cs b/OnixLabs.Security.Cryptography/EcdhPrivateKey.Export.cs index f55ef4e..055e94a 100644 --- a/OnixLabs.Security.Cryptography/EcdhPrivateKey.Export.cs +++ b/OnixLabs.Security.Cryptography/EcdhPrivateKey.Export.cs @@ -22,7 +22,7 @@ public sealed partial class EcdhPrivateKey /// /// Exports the current EC Diffie-Hellman cryptographic private key data. /// - /// Returns a new instance containing the EC Diffie-Hellman cryptographic private key data. + /// Returns a new array instance containing the EC Diffie-Hellman cryptographic private key data. public byte[] Export() { using ECDiffieHellman algorithm = ImportKeyData(); @@ -32,7 +32,7 @@ public byte[] Export() /// /// Exports the current EC Diffie-Hellman cryptographic private key data in PKCS #8 format. /// - /// Returns a new instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8() { using ECDiffieHellman algorithm = ImportKeyData(); @@ -44,7 +44,7 @@ public byte[] ExportPkcs8() /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using ECDiffieHellman algorithm = ImportKeyData(); @@ -56,7 +56,7 @@ public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the EC Diffie-Hellman cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using ECDiffieHellman algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/EcdhPrivateKey.To.cs b/OnixLabs.Security.Cryptography/EcdhPrivateKey.To.cs index 68a9251..3b2a34c 100644 --- a/OnixLabs.Security.Cryptography/EcdhPrivateKey.To.cs +++ b/OnixLabs.Security.Cryptography/EcdhPrivateKey.To.cs @@ -22,5 +22,5 @@ public sealed partial class EcdhPrivateKey /// Creates a new from the current instance. /// /// Returns a new from the current instance. - public override NamedPrivateKey ToNamedPrivateKey() => new(this, "ECDH"); + public override NamedPrivateKey ToNamedPrivateKey() => new(this, KeyName); } diff --git a/OnixLabs.Security.Cryptography/EcdhPublicKey.Convertible.cs b/OnixLabs.Security.Cryptography/EcdhPublicKey.Convertible.cs index ec117c0..f193a86 100644 --- a/OnixLabs.Security.Cryptography/EcdhPublicKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/EcdhPublicKey.Convertible.cs @@ -21,10 +21,10 @@ namespace OnixLabs.Security.Cryptography; public sealed partial class EcdhPublicKey { /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator EcdhPublicKey(byte[] value) => new(value); /// diff --git a/OnixLabs.Security.Cryptography/EcdhPublicKey.Export.cs b/OnixLabs.Security.Cryptography/EcdhPublicKey.Export.cs index 06038a0..c04f005 100644 --- a/OnixLabs.Security.Cryptography/EcdhPublicKey.Export.cs +++ b/OnixLabs.Security.Cryptography/EcdhPublicKey.Export.cs @@ -22,7 +22,7 @@ public sealed partial class EcdhPublicKey /// /// Exports the EC Diffie-Hellman cryptographic public key data. /// - /// Returns a new instance containing the EC Diffie-Hellman cryptographic public key data. + /// Returns a new array instance containing the EC Diffie-Hellman cryptographic public key data. public byte[] Export() { using ECDiffieHellman algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Convertible.cs b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Convertible.cs index 79ccd7c..5c0c1a7 100644 --- a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Convertible.cs @@ -21,10 +21,10 @@ namespace OnixLabs.Security.Cryptography; public sealed partial class EcdsaPrivateKey { /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator EcdsaPrivateKey(byte[] value) => new(value); /// diff --git a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Export.cs b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Export.cs index 92ae5eb..02d222c 100644 --- a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Export.cs +++ b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Export.cs @@ -22,7 +22,7 @@ public sealed partial class EcdsaPrivateKey /// /// Exports the ECDSA cryptographic private key data. /// - /// Returns a new instance containing the ECDSA cryptographic private key data. + /// Returns a new array instance containing the ECDSA cryptographic private key data. public byte[] Export() { using ECDsa algorithm = ImportKeyData(); @@ -32,7 +32,7 @@ public byte[] Export() /// /// Exports the ECDSA cryptographic private key data in PKCS #8 format. /// - /// Returns a new instance containing the ECDSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the ECDSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8() { using ECDsa algorithm = ImportKeyData(); @@ -44,7 +44,7 @@ public byte[] ExportPkcs8() /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the ECDSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the ECDSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using ECDsa algorithm = ImportKeyData(); @@ -56,7 +56,7 @@ public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the ECDSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the ECDSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using ECDsa algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Sign.cs b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Sign.cs index d35b0de..18e592f 100644 --- a/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Sign.cs +++ b/OnixLabs.Security.Cryptography/EcdsaPrivateKey.Sign.cs @@ -27,7 +27,7 @@ public sealed partial class EcdsaPrivateKey /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, HashAlgorithm algorithm, DSASignatureFormat format = default) { byte[] hash = algorithm.ComputeHash(data.ToArray()); @@ -42,7 +42,7 @@ public byte[] SignData(ReadOnlySpan data, HashAlgorithm algorithm, DSASign /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithm algorithm, DSASignatureFormat format = default) { byte[] hash = algorithm.ComputeHash(data.ToArray(), offset, count); @@ -55,7 +55,7 @@ public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgor /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(Stream data, HashAlgorithm algorithm, DSASignatureFormat format = default) { byte[] hash = algorithm.ComputeHash(data); @@ -68,7 +68,7 @@ public byte[] SignData(Stream data, HashAlgorithm algorithm, DSASignatureFormat /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(IBinaryConvertible data, HashAlgorithm algorithm, DSASignatureFormat format = default) { byte[] hash = algorithm.ComputeHash(data.AsReadOnlySpan()); @@ -81,7 +81,7 @@ public byte[] SignData(IBinaryConvertible data, HashAlgorithm algorithm, DSASign /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); @@ -96,7 +96,7 @@ public byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, DSA /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithmName algorithm, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); @@ -109,7 +109,7 @@ public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgor /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(Stream data, HashAlgorithmName algorithm, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); @@ -122,7 +122,7 @@ public byte[] SignData(Stream data, HashAlgorithmName algorithm, DSASignatureFor /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); @@ -134,7 +134,7 @@ public byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, DSA /// /// The hash to sign. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignHash(Hash hash, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); @@ -146,7 +146,7 @@ public byte[] SignHash(Hash hash, DSASignatureFormat format = default) /// /// The hash to sign. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignHash(ReadOnlySpan hash, DSASignatureFormat format = default) { using ECDsa key = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/EcdsaPublicKey.Convertible.cs b/OnixLabs.Security.Cryptography/EcdsaPublicKey.Convertible.cs index 6b86a7c..1ff4e45 100644 --- a/OnixLabs.Security.Cryptography/EcdsaPublicKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/EcdsaPublicKey.Convertible.cs @@ -21,10 +21,10 @@ namespace OnixLabs.Security.Cryptography; public sealed partial class EcdsaPublicKey { /// - /// Create a new instance from the specified value. + /// Create a new instance from the specified array. /// /// The value from which to create a new instance. - /// Returns a new instance from the specified value. + /// Returns a new instance from the specified array. public static implicit operator EcdsaPublicKey(byte[] value) => new(value); /// diff --git a/OnixLabs.Security.Cryptography/EcdsaPublicKey.Export.cs b/OnixLabs.Security.Cryptography/EcdsaPublicKey.Export.cs index ca1e41b..24a5eed 100644 --- a/OnixLabs.Security.Cryptography/EcdsaPublicKey.Export.cs +++ b/OnixLabs.Security.Cryptography/EcdsaPublicKey.Export.cs @@ -21,7 +21,7 @@ public sealed partial class EcdsaPublicKey /// /// Exports the ECDSA cryptographic public key data. /// - /// Returns a new instance containing the ECDSA cryptographic public key data. + /// Returns a new array instance containing the ECDSA cryptographic public key data. public byte[] Export() { using ECDsa algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/Extensions.HashAlgorithm.cs b/OnixLabs.Security.Cryptography/Extensions.HashAlgorithm.cs index 8d86e62..573eb28 100644 --- a/OnixLabs.Security.Cryptography/Extensions.HashAlgorithm.cs +++ b/OnixLabs.Security.Cryptography/Extensions.HashAlgorithm.cs @@ -23,7 +23,7 @@ namespace OnixLabs.Security.Cryptography; /// -/// Provides extension methods for hash algorithms. +/// Provides extension methods for instances. /// [EditorBrowsable(EditorBrowsableState.Never)] public static class HashAlgorithmExtensions @@ -31,159 +31,157 @@ public static class HashAlgorithmExtensions private const string ComputeHashFailed = "Failed to compute a hash for the specified input data."; /// - /// Computes the hash value for the specified value. + /// Provides extension methods for instances. /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, ReadOnlySpan data, int rounds = 1) + /// The current instance. + extension(HashAlgorithm algorithm) { - Span destination = stackalloc byte[algorithm.HashSize / 8]; - - if (!algorithm.TryComputeHash(data, destination, 0, data.Length, rounds, out int _)) - throw new CryptographicException(ComputeHashFailed); - - return destination.ToArray(); - } - - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The offset into the input from which to begin using data. - /// The number of bytes in the input to use as data. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, ReadOnlySpan data, int offset, int count, int rounds = 1) - { - ReadOnlySpan source = data.Slice(offset, count); - Span destination = stackalloc byte[algorithm.HashSize / 8]; - - if (!algorithm.TryComputeHash(source, destination, 0, source.Length, rounds, out int _)) - throw new CryptographicException(ComputeHashFailed); - - return destination.ToArray(); - } - - /// - /// Computes the hash value for the specified . - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The which will be used to convert the specified . - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, ReadOnlySpan data, Encoding? encoding = null, int rounds = 1) => - algorithm.ComputeHash(encoding.GetOrDefault().GetBytes(data.ToArray()), rounds); + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(ReadOnlySpan data, int rounds = 1) + { + Span destination = stackalloc byte[algorithm.HashSize / 8]; - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, IBinaryConvertible data, int rounds = 1) => - algorithm.ComputeHash(data.AsReadOnlySpan(), rounds); + if (!algorithm.TryComputeHash(data, destination, 0, data.Length, rounds, out int _)) + throw new CryptographicException(ComputeHashFailed); - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The offset into the input from which to begin using data. - /// The number of bytes in the input to use as data. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, IBinaryConvertible data, int offset, int count, int rounds = 1) => - algorithm.ComputeHash(data.AsReadOnlySpan(), offset, count, rounds); + return destination.ToArray(); + } - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, ISpanBinaryConvertible data, int rounds = 1) => - algorithm.ComputeHash(data.AsReadOnlySpan(), rounds); + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The offset into the input from which to begin using data. + /// The number of bytes in the input to use as data. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(ReadOnlySpan data, int offset, int count, int rounds = 1) + { + ReadOnlySpan source = data.Slice(offset, count); + Span destination = stackalloc byte[algorithm.HashSize / 8]; - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The offset into the input from which to begin using data. - /// The number of bytes in the input to use as data. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, ISpanBinaryConvertible data, int offset, int count, int rounds = 1) => - algorithm.ComputeHash(data.AsReadOnlySpan(), offset, count, rounds); + if (!algorithm.TryComputeHash(source, destination, 0, source.Length, rounds, out int _)) + throw new CryptographicException(ComputeHashFailed); - /// - /// Computes the hash value for the specified value. - /// - /// The which will be used to compute a hash value. - /// The input data to compute the hash for. - /// The number of rounds that the input data should be hashed. - /// Returns the computed hash value. - /// If the hash could not be computed for the specified input data. - public static byte[] ComputeHash(this HashAlgorithm algorithm, Stream stream, int rounds) => rounds is 1 - ? algorithm.ComputeHash(stream) - : algorithm.ComputeHash(algorithm.ComputeHash(stream), rounds - 1); + return destination.ToArray(); + } - /// - /// Attempts to compute the hash value for the specified . - /// - /// The which will be used to compute a hash value. - /// The input to compute the hash code for. - /// The buffer to receive the hash value. - /// The offset into the input from which to begin using data. - /// The number of bytes in the input to use as data. - /// The number of rounds that the input data should be hashed. - /// When this method returns, the total number of bytes written into . This parameter is treated as uninitialized. - /// Returns if is long enough to receive the hash value; otherwise, . - // ReSharper disable once MemberCanBePrivate.Global - public static bool TryComputeHash(this HashAlgorithm algorithm, ReadOnlySpan source, Span destination, int offset, int count, int rounds, out int bytesWritten) - { - try + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The which will be used to convert the specified . + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(ReadOnlySpan data, Encoding? encoding = null, int rounds = 1) => + algorithm.ComputeHash(encoding.GetOrDefault().GetBytes(data.ToArray()), rounds); + + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(IBinaryConvertible data, int rounds = 1) => + algorithm.ComputeHash(data.AsReadOnlySpan(), rounds); + + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The offset into the input from which to begin using data. + /// The number of bytes in the input to use as data. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(IBinaryConvertible data, int offset, int count, int rounds = 1) => + algorithm.ComputeHash(data.AsReadOnlySpan(), offset, count, rounds); + + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(ISpanBinaryConvertible data, int rounds = 1) => + algorithm.ComputeHash(data.AsReadOnlySpan(), rounds); + + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The offset into the input from which to begin using data. + /// The number of bytes in the input to use as data. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(ISpanBinaryConvertible data, int offset, int count, int rounds = 1) => + algorithm.ComputeHash(data.AsReadOnlySpan(), offset, count, rounds); + + /// + /// Computes the hash value for the specified value. + /// + /// The input data to compute the hash for. + /// The number of rounds that the input data should be hashed. + /// Returns the computed hash value. + /// If the hash could not be computed for the specified input data. + public byte[] ComputeHash(Stream stream, int rounds) => rounds is 1 + ? algorithm.ComputeHash(stream) + : algorithm.ComputeHash(algorithm.ComputeHash(stream), rounds - 1); + + /// + /// Attempts to compute the hash value for the specified instance. + /// + /// The input to compute the hash code for. + /// The buffer to receive the hash value. + /// The offset into the input from which to begin using data. + /// The number of bytes in the input to use as data. + /// The number of rounds that the input data should be hashed. + /// When this method returns, the total number of bytes written into . This parameter is treated as uninitialized. + /// Returns if is long enough to receive the hash value; otherwise, . + // ReSharper disable once MemberCanBePrivate.Global + public bool TryComputeHash(ReadOnlySpan source, Span destination, int offset, int count, int rounds, out int bytesWritten) { - if (rounds < 1 || destination.Length < algorithm.HashSize / 8) - { - bytesWritten = 0; - return false; - } - - source = source.Slice(offset, count); - int result = 0; - - while (rounds-- > 0) + try { - if (!algorithm.TryComputeHash(source, destination, out result)) + if (rounds < 1 || destination.Length < algorithm.HashSize / 8) { bytesWritten = 0; return false; } - source = destination; - } + source = source.Slice(offset, count); + int result = 0; - bytesWritten = result; - return true; - } - catch - { - bytesWritten = 0; - return false; + while (rounds-- > 0) + { + if (!algorithm.TryComputeHash(source, destination, out result)) + { + bytesWritten = 0; + return false; + } + + source = destination; + } + + bytesWritten = result; + return true; + } + catch + { + bytesWritten = 0; + return false; + } } } } diff --git a/OnixLabs.Security.Cryptography/Extensions.cs b/OnixLabs.Security.Cryptography/Extensions.cs index 1a3357b..3bfc4b2 100644 --- a/OnixLabs.Security.Cryptography/Extensions.cs +++ b/OnixLabs.Security.Cryptography/Extensions.cs @@ -18,37 +18,28 @@ namespace OnixLabs.Security.Cryptography; /// -/// Provides extension methods for byte arrays and read-only spans. +/// Provides extension methods for instances. /// // ReSharper disable UnusedMethodReturnValue.Global [EditorBrowsable(EditorBrowsableState.Never)] public static class Extensions { /// - /// Converts the current into a new instance. + /// /// Provides extension methods for instances. /// - /// The value to convert. - /// Returns a new instance. - public static Hash ToHash(this byte[] value) => value; + /// The current instance. + extension(ReadOnlySpan receiver) + { + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Hash ToHash() => receiver; - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Hash ToHash(this ReadOnlySpan value) => value; - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Secret ToSecret(this byte[] value) => value; - - /// - /// Converts the current into a new instance. - /// - /// The value to convert. - /// Returns a new instance. - public static Secret ToSecret(this ReadOnlySpan value) => value; + /// + /// Converts the current into a new instance. + /// + /// Returns a new instance. + public Secret ToSecret() => receiver; + } } diff --git a/OnixLabs.Security.Cryptography/Hash.Compute.cs b/OnixLabs.Security.Cryptography/Hash.Compute.cs index 5ba6484..680670b 100644 --- a/OnixLabs.Security.Cryptography/Hash.Compute.cs +++ b/OnixLabs.Security.Cryptography/Hash.Compute.cs @@ -26,7 +26,7 @@ public readonly partial struct Hash /// Computes the hash of the specified data, using the specified . /// /// The which will be used to compute the hash. - /// The data from which to compute a hash. + /// The array data from which to compute a hash. /// The number of rounds that the input data should be hashed. /// Returns a cryptographic hash of the specified data. public static Hash Compute(HashAlgorithm algorithm, byte[] data, int rounds = 1) => @@ -36,8 +36,8 @@ public static Hash Compute(HashAlgorithm algorithm, byte[] data, int rounds = 1) /// Computes the hash of the specified data, using the specified . /// /// The which will be used to compute the hash. - /// The data from which to compute a hash. - /// The offset into the from which to begin using data. + /// The array data from which to compute a hash. + /// The offset into the array from which to begin using data. /// The number of bytes in the array to use as data. /// The number of rounds that the input data should be hashed. /// Returns a cryptographic hash of the specified data. diff --git a/OnixLabs.Security.Cryptography/Hash.Convertible.cs b/OnixLabs.Security.Cryptography/Hash.Convertible.cs index a73e4f2..c8c51e7 100644 --- a/OnixLabs.Security.Cryptography/Hash.Convertible.cs +++ b/OnixLabs.Security.Cryptography/Hash.Convertible.cs @@ -20,15 +20,15 @@ namespace OnixLabs.Security.Cryptography; public readonly partial struct Hash { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; /// diff --git a/OnixLabs.Security.Cryptography/Hash.cs b/OnixLabs.Security.Cryptography/Hash.cs index 171e342..ef2a880 100644 --- a/OnixLabs.Security.Cryptography/Hash.cs +++ b/OnixLabs.Security.Cryptography/Hash.cs @@ -25,6 +25,8 @@ namespace OnixLabs.Security.Cryptography; /// The underlying value of the cryptographic hash. public readonly partial struct Hash(ReadOnlySpan value) : ICryptoPrimitive, IValueComparable, ISpanParsable { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -41,8 +43,6 @@ public Hash(byte value, int length) : this(Enumerable.Repeat(value, length).ToAr { } - private readonly byte[] value = value.ToArray(); - /// /// Gets the length of the current in bytes. /// diff --git a/OnixLabs.Security.Cryptography/IEcdsaPrivateKey.cs b/OnixLabs.Security.Cryptography/IEcdsaPrivateKey.cs index 4494cbb..f63911e 100644 --- a/OnixLabs.Security.Cryptography/IEcdsaPrivateKey.cs +++ b/OnixLabs.Security.Cryptography/IEcdsaPrivateKey.cs @@ -34,7 +34,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, HashAlgorithm algorithm, DSASignatureFormat format = default); /// @@ -45,7 +45,7 @@ public interface IEcdsaPrivateKey : /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithm algorithm, DSASignatureFormat format = default); /// @@ -54,7 +54,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(Stream data, HashAlgorithm algorithm, DSASignatureFormat format = default); /// @@ -63,7 +63,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(IBinaryConvertible data, HashAlgorithm algorithm, DSASignatureFormat format = default); /// @@ -72,7 +72,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, DSASignatureFormat format = default); /// @@ -83,7 +83,7 @@ public interface IEcdsaPrivateKey : /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithmName algorithm, DSASignatureFormat format = default); /// @@ -92,7 +92,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(Stream data, HashAlgorithmName algorithm, DSASignatureFormat format = default); /// @@ -101,7 +101,7 @@ public interface IEcdsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, DSASignatureFormat format = default); /// @@ -109,7 +109,7 @@ public interface IEcdsaPrivateKey : /// /// The hash to sign. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignHash(Hash hash, DSASignatureFormat format = default); /// @@ -117,6 +117,6 @@ public interface IEcdsaPrivateKey : /// /// The hash to sign. /// The digital signature format which will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignHash(ReadOnlySpan hash, DSASignatureFormat format = default); } diff --git a/OnixLabs.Security.Cryptography/IPrivateKeyExportable.cs b/OnixLabs.Security.Cryptography/IPrivateKeyExportable.cs index 59b93f2..42e133d 100644 --- a/OnixLabs.Security.Cryptography/IPrivateKeyExportable.cs +++ b/OnixLabs.Security.Cryptography/IPrivateKeyExportable.cs @@ -25,13 +25,13 @@ public interface IPrivateKeyExportable /// /// Exports the cryptographic private key data. /// - /// Returns a new instance containing the cryptographic private key data. + /// Returns a new array instance containing the cryptographic private key data. byte[] Export(); /// /// Exports the cryptographic private key data in PKCS #8 format. /// - /// Returns a new instance containing the cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the cryptographic private key data in PKCS #8 format. byte[] ExportPkcs8(); /// @@ -39,7 +39,7 @@ public interface IPrivateKeyExportable /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the cryptographic private key data in PKCS #8 format. byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters); /// @@ -47,7 +47,7 @@ public interface IPrivateKeyExportable /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the cryptographic private key data in PKCS #8 format. byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters); /// diff --git a/OnixLabs.Security.Cryptography/IPublicKeyExportable.cs b/OnixLabs.Security.Cryptography/IPublicKeyExportable.cs index 9209246..786d815 100644 --- a/OnixLabs.Security.Cryptography/IPublicKeyExportable.cs +++ b/OnixLabs.Security.Cryptography/IPublicKeyExportable.cs @@ -22,7 +22,7 @@ public interface IPublicKeyExportable /// /// Exports the cryptographic public key data. /// - /// Returns a new instance containing the cryptographic public key data. + /// Returns a new array instance containing the cryptographic public key data. byte[] Export(); /// diff --git a/OnixLabs.Security.Cryptography/IRsaPrivateKey.cs b/OnixLabs.Security.Cryptography/IRsaPrivateKey.cs index 8fddf73..9017528 100644 --- a/OnixLabs.Security.Cryptography/IRsaPrivateKey.cs +++ b/OnixLabs.Security.Cryptography/IRsaPrivateKey.cs @@ -34,7 +34,7 @@ public interface IRsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, RSASignaturePadding padding); /// @@ -45,7 +45,7 @@ public interface IRsaPrivateKey : /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithmName algorithm, RSASignaturePadding padding); /// @@ -54,7 +54,7 @@ public interface IRsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(Stream data, HashAlgorithmName algorithm, RSASignaturePadding padding); /// @@ -63,7 +63,7 @@ public interface IRsaPrivateKey : /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, RSASignaturePadding padding); /// @@ -72,7 +72,7 @@ public interface IRsaPrivateKey : /// The hash to sign. /// The hash algorithm that will be used to hash the input hash. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignHash(Hash hash, HashAlgorithmName algorithm, RSASignaturePadding padding); /// @@ -81,6 +81,6 @@ public interface IRsaPrivateKey : /// The hash to sign. /// The hash algorithm that will be used to hash the input hash. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. byte[] SignHash(ReadOnlySpan hash, HashAlgorithmName algorithm, RSASignaturePadding padding); } diff --git a/OnixLabs.Security.Cryptography/MerkleTree.Convertible.cs b/OnixLabs.Security.Cryptography/MerkleTree.Convertible.cs index e0d9a49..51c9c59 100644 --- a/OnixLabs.Security.Cryptography/MerkleTree.Convertible.cs +++ b/OnixLabs.Security.Cryptography/MerkleTree.Convertible.cs @@ -19,14 +19,14 @@ namespace OnixLabs.Security.Cryptography; public abstract partial class MerkleTree { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => Hash.AsReadOnlyMemory(); /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => Hash.AsReadOnlySpan(); } diff --git a/OnixLabs.Security.Cryptography/NamedHash.Convertible.cs b/OnixLabs.Security.Cryptography/NamedHash.Convertible.cs index ab5fa33..b456190 100644 --- a/OnixLabs.Security.Cryptography/NamedHash.Convertible.cs +++ b/OnixLabs.Security.Cryptography/NamedHash.Convertible.cs @@ -19,16 +19,16 @@ namespace OnixLabs.Security.Cryptography; public readonly partial record struct NamedHash { /// - /// Gets the underlying representation of the underlying instance as a new instance. + /// Gets the underlying array representation of the underlying instance as a new instance. /// This method only obtains the bytes representing the hash value. The name of the hash will not be encoded into the resulting span. /// - /// Return the underlying representation of the underlying instance as a new instance. + /// Return the underlying array representation of the underlying instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => Hash.AsReadOnlyMemory(); /// - /// Gets the underlying representation of the underlying instance as a new instance. + /// Gets the underlying array representation of the underlying instance as a new instance. /// This method only obtains the bytes representing the hash value. The name of the hash will not be encoded into the resulting span. /// - /// Return the underlying representation of the underlying instance as a new instance. + /// Return the underlying array representation of the underlying instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => Hash.AsReadOnlySpan(); } diff --git a/OnixLabs.Security.Cryptography/NamedPrivateKey.Convertible.cs b/OnixLabs.Security.Cryptography/NamedPrivateKey.Convertible.cs index a64bd59..3fd0063 100644 --- a/OnixLabs.Security.Cryptography/NamedPrivateKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/NamedPrivateKey.Convertible.cs @@ -19,16 +19,16 @@ namespace OnixLabs.Security.Cryptography; public readonly partial record struct NamedPrivateKey { /// - /// Gets the underlying representation of the underlying instance as a new instance. + /// Gets the underlying array representation of the underlying instance as a new instance. /// This method only obtains the bytes representing the private key value. The name of the private key will not be encoded into the resulting span. /// - /// Return the underlying representation of the underlying instance as a new instance. + /// Return the underlying array representation of the underlying instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => PrivateKey.AsReadOnlyMemory(); /// - /// Gets the underlying representation of the underlying instance as a new instance. + /// Gets the underlying array representation of the underlying instance as a new instance. /// This method only obtains the bytes representing the private key value. The name of the private key will not be encoded into the resulting span. /// - /// Return the underlying representation of the underlying instance as a new instance. + /// Return the underlying array representation of the underlying instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => PrivateKey.AsReadOnlySpan(); } diff --git a/OnixLabs.Security.Cryptography/NamedPublicKey.Convertible.cs b/OnixLabs.Security.Cryptography/NamedPublicKey.Convertible.cs index 2e65ab9..240b4e4 100644 --- a/OnixLabs.Security.Cryptography/NamedPublicKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/NamedPublicKey.Convertible.cs @@ -19,16 +19,16 @@ namespace OnixLabs.Security.Cryptography; public readonly partial record struct NamedPublicKey { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// This method only obtains the bytes representing the public key value. The name of the public key will not be encoded into the resulting span. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => PublicKey.AsReadOnlyMemory(); /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// This method only obtains the bytes representing the public key value. The name of the public key will not be encoded into the resulting span. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => PublicKey.AsReadOnlySpan(); } diff --git a/OnixLabs.Security.Cryptography/PrivateKey.Convertible.cs b/OnixLabs.Security.Cryptography/PrivateKey.Convertible.cs index 3b3d95f..8f8f395 100644 --- a/OnixLabs.Security.Cryptography/PrivateKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/PrivateKey.Convertible.cs @@ -19,14 +19,14 @@ namespace OnixLabs.Security.Cryptography; public abstract partial class PrivateKey { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => KeyData; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => KeyData; } diff --git a/OnixLabs.Security.Cryptography/PrivateKey.cs b/OnixLabs.Security.Cryptography/PrivateKey.cs index 01417e6..38825e9 100644 --- a/OnixLabs.Security.Cryptography/PrivateKey.cs +++ b/OnixLabs.Security.Cryptography/PrivateKey.cs @@ -23,7 +23,6 @@ public abstract partial class PrivateKey : ICryptoPrimitive { // ReSharper disable once HeapView.ObjectAllocation.Evident private readonly ProtectedData protectedData = new(); - private readonly byte[] encryptedKeyData; /// /// Initializes a new instance of the class. @@ -31,11 +30,11 @@ public abstract partial class PrivateKey : ICryptoPrimitive /// The underlying key data of the cryptographic private key. protected PrivateKey(ReadOnlySpan keyData) { - encryptedKeyData = protectedData.Encrypt(keyData.ToArray()); + KeyData = protectedData.Encrypt(keyData.ToArray()); } /// /// Gets the cryptographic private key data. /// - protected byte[] KeyData => protectedData.Decrypt(encryptedKeyData); + protected byte[] KeyData => protectedData.Decrypt(field); } diff --git a/OnixLabs.Security.Cryptography/PublicKey.Convertible.cs b/OnixLabs.Security.Cryptography/PublicKey.Convertible.cs index ec190ee..8fde4c3 100644 --- a/OnixLabs.Security.Cryptography/PublicKey.Convertible.cs +++ b/OnixLabs.Security.Cryptography/PublicKey.Convertible.cs @@ -19,14 +19,14 @@ namespace OnixLabs.Security.Cryptography; public abstract partial class PublicKey { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => KeyData; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => KeyData; } diff --git a/OnixLabs.Security.Cryptography/RsaPrivateKey.Export.cs b/OnixLabs.Security.Cryptography/RsaPrivateKey.Export.cs index 02a225c..254f788 100644 --- a/OnixLabs.Security.Cryptography/RsaPrivateKey.Export.cs +++ b/OnixLabs.Security.Cryptography/RsaPrivateKey.Export.cs @@ -22,7 +22,7 @@ public sealed partial class RsaPrivateKey /// /// Exports the RSA cryptographic private key data. /// - /// Returns a new instance containing the RSA cryptographic private key data. + /// Returns a new array instance containing the RSA cryptographic private key data. public byte[] Export() { using RSA algorithm = ImportKeyData(); @@ -32,7 +32,7 @@ public byte[] Export() /// /// Exports the RSA cryptographic private key data in PKCS #8 format. /// - /// Returns a new instance containing the RSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the RSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8() { using RSA algorithm = ImportKeyData(); @@ -44,7 +44,7 @@ public byte[] ExportPkcs8() /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the RSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the RSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using RSA algorithm = ImportKeyData(); @@ -56,7 +56,7 @@ public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) /// /// The password to use for encryption. /// The parameters required for password based encryption. - /// Returns a new instance containing the RSA cryptographic private key data in PKCS #8 format. + /// Returns a new array instance containing the RSA cryptographic private key data in PKCS #8 format. public byte[] ExportPkcs8(ReadOnlySpan password, PbeParameters parameters) { using RSA algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/RsaPrivateKey.Sign.cs b/OnixLabs.Security.Cryptography/RsaPrivateKey.Sign.cs index 40a68f1..feac7f6 100644 --- a/OnixLabs.Security.Cryptography/RsaPrivateKey.Sign.cs +++ b/OnixLabs.Security.Cryptography/RsaPrivateKey.Sign.cs @@ -27,7 +27,7 @@ public sealed partial class RsaPrivateKey /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); @@ -42,7 +42,7 @@ public byte[] SignData(ReadOnlySpan data, HashAlgorithmName algorithm, RSA /// The number of bytes in the array to use as data. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); @@ -55,7 +55,7 @@ public byte[] SignData(ReadOnlySpan data, int offset, int count, HashAlgor /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(Stream data, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); @@ -68,7 +68,7 @@ public byte[] SignData(Stream data, HashAlgorithmName algorithm, RSASignaturePad /// The input data to hash and sign. /// The hash algorithm that will be used to hash the input data. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); @@ -81,7 +81,7 @@ public byte[] SignData(IBinaryConvertible data, HashAlgorithmName algorithm, RSA /// The hash to sign. /// The hash algorithm that will be used to hash the input hash. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignHash(Hash hash, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); @@ -94,7 +94,7 @@ public byte[] SignHash(Hash hash, HashAlgorithmName algorithm, RSASignaturePaddi /// The hash to sign. /// The hash algorithm that will be used to hash the input hash. /// The RSA signature padding mode that will be used to generate the cryptographic digital signature. - /// Returns a new instance containing the cryptographic digital signature. + /// Returns a new array instance containing the cryptographic digital signature. public byte[] SignHash(ReadOnlySpan hash, HashAlgorithmName algorithm, RSASignaturePadding padding) { using RSA key = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/RsaPublicKey.Export.cs b/OnixLabs.Security.Cryptography/RsaPublicKey.Export.cs index d99bcf9..4637633 100644 --- a/OnixLabs.Security.Cryptography/RsaPublicKey.Export.cs +++ b/OnixLabs.Security.Cryptography/RsaPublicKey.Export.cs @@ -21,7 +21,7 @@ public sealed partial class RsaPublicKey /// /// Exports the RSA cryptographic public key data. /// - /// Returns a new instance containing the RSA cryptographic public key data. + /// Returns a new array instance containing the RSA cryptographic public key data. public byte[] Export() { using RSA algorithm = ImportKeyData(); diff --git a/OnixLabs.Security.Cryptography/Salt.Convertible.cs b/OnixLabs.Security.Cryptography/Salt.Convertible.cs index 1c86d1a..89356c8 100644 --- a/OnixLabs.Security.Cryptography/Salt.Convertible.cs +++ b/OnixLabs.Security.Cryptography/Salt.Convertible.cs @@ -19,14 +19,14 @@ namespace OnixLabs.Security.Cryptography; public readonly partial struct Salt { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => value; /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => value; } diff --git a/OnixLabs.Security.Cryptography/Salt.cs b/OnixLabs.Security.Cryptography/Salt.cs index e86db09..2a23cec 100644 --- a/OnixLabs.Security.Cryptography/Salt.cs +++ b/OnixLabs.Security.Cryptography/Salt.cs @@ -24,6 +24,8 @@ namespace OnixLabs.Security.Cryptography; /// The underlying value of the salt. public readonly partial struct Salt(ReadOnlySpan value) : ICryptoPrimitive { + private readonly byte[] value = value.ToArray(); + /// /// Initializes a new instance of the struct. /// @@ -31,8 +33,6 @@ public readonly partial struct Salt(ReadOnlySpan value) : ICryptoPrimitive // ReSharper disable once MemberCanBePrivate.Global public Salt(ReadOnlySequence value) : this(ReadOnlySpan.Empty) => value.CopyTo(out this.value); - private readonly byte[] value = value.ToArray(); - /// /// Gets the length of the current in bytes. /// diff --git a/OnixLabs.Security.Cryptography/Secret.Convertible.cs b/OnixLabs.Security.Cryptography/Secret.Convertible.cs index 64d047e..954492c 100644 --- a/OnixLabs.Security.Cryptography/Secret.Convertible.cs +++ b/OnixLabs.Security.Cryptography/Secret.Convertible.cs @@ -21,15 +21,15 @@ namespace OnixLabs.Security.Cryptography; public readonly partial struct Secret { /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlyMemory AsReadOnlyMemory() => protectedData.Decrypt(encryptedValue); /// - /// Gets the underlying representation of the current instance as a new instance. + /// Gets the underlying array representation of the current instance as a new instance. /// - /// Return the underlying representation of the current instance as a new instance. + /// Return the underlying array representation of the current instance as a new instance. public ReadOnlySpan AsReadOnlySpan() => protectedData.Decrypt(encryptedValue); /// diff --git a/OnixLabs.Security.Cryptography/Sha3.Permute.cs b/OnixLabs.Security.Cryptography/Sha3.Permute.cs index 776927e..b556979 100644 --- a/OnixLabs.Security.Cryptography/Sha3.Permute.cs +++ b/OnixLabs.Security.Cryptography/Sha3.Permute.cs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System.Collections.Generic; - namespace OnixLabs.Security.Cryptography; public abstract partial class Sha3 @@ -22,7 +20,7 @@ public abstract partial class Sha3 /// Performs the FIPS 202 SHA-3 permutation. /// /// The state upon which to perform the permutation. - private static void Permute(IList state) + private static void Permute(ulong[] state) { const int hashRounds = 24; diff --git a/README.md b/README.md index 9aa39c6..d3f33e0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -![ONIX Labs](https://raw.githubusercontent.com/onix-labs/onixlabs-website/main/src/assets/images/logo/full/original/original-md.png) +![ONIX Labs](https://raw.githubusercontent.com/onix-labs/onixlabs-website/refs/heads/main/OnixLabs.Web/wwwroot/onixlabs/images/logo/logo-full-light.svg) # ONIXLabs .NET Library diff --git a/global.json b/global.json index 60af8e2..323afc1 100644 --- a/global.json +++ b/global.json @@ -1,7 +1,10 @@ { "sdk": { - "version": "9.0.100", + "version": "10.0.x", "rollForward": "latestFeature", "allowPrerelease": false + }, + "test": { + "runner": "Microsoft.Testing.Platform" } }