diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index 81d6268..1e8e25f 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -3,7 +3,6 @@
on:
push:
branches: ["main"]
-
workflow_dispatch:
permissions:
diff --git a/src/LightResults/LightResults.csproj b/src/LightResults/LightResults.csproj
index da8767a..fbc67e9 100644
--- a/src/LightResults/LightResults.csproj
+++ b/src/LightResults/LightResults.csproj
@@ -6,7 +6,7 @@
enable
LightResults
latest
- 8.0.9
+ 9.0.0-preview.1
LightResults
Jean-Sebastien Carle
An extremely light and modern Result Pattern library.
@@ -19,8 +19,8 @@
https://github.com/jscarle/LightResults
git
result results pattern fluentresults error handling
- 8.0.9.0
- 8.0.9.0
+ 9.0.0.0
+ 9.0.0.0
en-US
true
snupkg
@@ -39,6 +39,7 @@
+
diff --git a/src/LightResults/Result.cs b/src/LightResults/Result.cs
index 9e0d463..c736134 100644
--- a/src/LightResults/Result.cs
+++ b/src/LightResults/Result.cs
@@ -4,7 +4,7 @@
namespace LightResults;
/// Represents a result.
-public sealed class Result :
+public readonly struct Result : IEquatable,
#if NET7_0_OR_GREATER
IActionableResult
#else
@@ -12,13 +12,29 @@ public sealed class Result :
#endif
{
///
- public bool IsSuccess => _errors.Length == 0;
+ public bool IsSuccess
+ {
+ get
+ {
+ if (_errors is null)
+ return true;
+ return _errors.Value.Length == 0;
+ }
+ }
///
- public bool IsFailed => _errors.Length != 0;
+ public bool IsFailed
+ {
+ get
+ {
+ if (_errors is null)
+ return false;
+ return _errors.Value.Length != 0;
+ }
+ }
///
- public IReadOnlyCollection Errors => _errors;
+ public IReadOnlyCollection Errors => _errors ?? ImmutableArray.Empty;
///
public IError Error
@@ -28,15 +44,16 @@ public IError Error
if (IsSuccess)
throw new InvalidOperationException($"{nameof(Result)} is successful. {nameof(Error)} is not set.");
- return _errors[0];
+ return _errors!.Value[0];
}
}
private static readonly Result OkResult = new();
private static readonly Result FailedResult = new(LightResults.Error.Empty);
- private readonly ImmutableArray _errors;
+ private readonly ImmutableArray? _errors;
- private Result()
+ /// Initializes a new instance of the struct.
+ public Result()
{
_errors = ImmutableArray.Empty;
}
@@ -180,13 +197,16 @@ public static Result Fail(IEnumerable errors)
///
public bool HasError() where TError : IError
{
+ if (_errors is null)
+ return false;
+
// Do not convert to LINQ, this creates unnecessary heap allocations.
// For is the most efficient way to loop. It is the fastest and does not allocate.
// ReSharper disable once ForCanBeConvertedToForeach
// ReSharper disable once LoopCanBeConvertedToQuery
- for (var index = 0; index < _errors.Length; index++)
+ for (var index = 0; index < _errors!.Value.Length; index++)
{
- var error = _errors[index];
+ var error = _errors!.Value[index];
if (error is TError)
return true;
}
@@ -200,10 +220,51 @@ public override string ToString()
if (IsSuccess)
return $"{nameof(Result)} {{ IsSuccess = True }}";
- if (_errors[0].Message.Length == 0)
+ if (_errors!.Value[0].Message.Length == 0)
return $"{nameof(Result)} {{ IsSuccess = False }}";
- var errorString = StringHelper.GetResultErrorString(_errors);
+ var errorString = StringHelper.GetResultErrorString(_errors!.Value);
return StringHelper.GetResultString(nameof(Result), "False", errorString);
}
-}
\ No newline at end of file
+
+ /// Determines whether two instances are equal.
+ /// The instance to compare with this instance.
+ /// true if the specified is equal to this instance; otherwise, false.
+ public bool Equals(Result other)
+ {
+ return Nullable.Equals(_errors, other._errors);
+ }
+
+ /// Determines whether the specified object is equal to this instance.
+ /// The object to compare with this instance.
+ /// true if the specified object is equal to this instance; otherwise, false.
+ public override bool Equals(object? obj)
+ {
+ return obj is Result other && Equals(other);
+ }
+
+ /// Returns the hash code for this instance.
+ /// A 32-bit signed integer hash code.
+ public override int GetHashCode()
+ {
+ return _errors.GetHashCode();
+ }
+
+ /// Determines whether two instances are equal.
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the specified instances are equal; otherwise, false.
+ public static bool operator ==(Result left, Result right)
+ {
+ return left.Equals(right);
+ }
+
+ /// Determines whether two instances are not equal.
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the specified instances are not equal; otherwise, false.
+ public static bool operator !=(Result left, Result right)
+ {
+ return !left.Equals(right);
+ }
+}
diff --git a/src/LightResults/Result`1.cs b/src/LightResults/Result`1.cs
index 4c2e0b5..64ee92b 100644
--- a/src/LightResults/Result`1.cs
+++ b/src/LightResults/Result`1.cs
@@ -6,7 +6,7 @@ namespace LightResults;
// ReSharper disable StaticMemberInGenericType
/// Represents a result.
/// The type of the value in the result.
-public sealed class Result :
+public readonly struct Result : IEquatable>,
#if NET7_0_OR_GREATER
IActionableResult>
#else
@@ -14,13 +14,29 @@ public sealed class Result :
#endif
{
///
- public bool IsSuccess => _errors.Length == 0;
+ public bool IsSuccess
+ {
+ get
+ {
+ if (_errors is null)
+ return true;
+ return _errors.Value.Length == 0;
+ }
+ }
///
- public bool IsFailed => _errors.Length != 0;
+ public bool IsFailed
+ {
+ get
+ {
+ if (_errors is null)
+ return false;
+ return _errors.Value.Length != 0;
+ }
+ }
///
- public IReadOnlyCollection Errors => _errors;
+ public IReadOnlyCollection Errors => _errors ?? ImmutableArray.Empty;
///
public IError Error
@@ -30,7 +46,7 @@ public IError Error
if (IsSuccess)
throw new InvalidOperationException($"{nameof(Result)} is successful. {nameof(Error)} is not set.");
- return _errors[0];
+ return _errors!.Value[0];
}
}
@@ -48,10 +64,11 @@ public TValue Value
}
private static readonly Result FailedResult = new(LightResults.Error.Empty);
- private readonly ImmutableArray _errors;
+ private readonly ImmutableArray? _errors;
private readonly TValue? _valueOrDefault;
- private Result()
+ /// Initializes a new instance of the struct.
+ public Result()
{
_errors = ImmutableArray.Empty;
}
@@ -133,13 +150,16 @@ public static Result Fail(IEnumerable errors)
///
public bool HasError() where TError : IError
{
+ if (_errors is null)
+ return false;
+
// Do not convert to LINQ, this creates unnecessary heap allocations.
// For is the most efficient way to loop. It is the fastest and does not allocate.
// ReSharper disable once ForCanBeConvertedToForeach
// ReSharper disable once LoopCanBeConvertedToQuery
- for (var index = 0; index < _errors.Length; index++)
+ for (var index = 0; index < _errors!.Value.Length; index++)
{
- var error = _errors[index];
+ var error = _errors!.Value[index];
if (error is TError)
return true;
}
@@ -156,10 +176,52 @@ public override string ToString()
return StringHelper.GetResultString(nameof(Result), "True", valueString);
}
- if (_errors[0].Message.Length == 0)
+ if (_errors!.Value[0].Message.Length == 0)
return $"{nameof(Result)} {{ IsSuccess = False }}";
- var errorString = StringHelper.GetResultErrorString(_errors);
+ var errorString = StringHelper.GetResultErrorString(_errors!.Value);
return StringHelper.GetResultString(nameof(Result), "False", errorString);
}
-}
\ No newline at end of file
+
+ /// Determines whether two instances are equal.
+ /// The instance to compare with this instance.
+ /// true if the specified is equal to this instance; otherwise, false.
+ public bool Equals(Result other)
+ {
+ return Nullable.Equals(_errors, other._errors) && EqualityComparer.Default.Equals(_valueOrDefault, other._valueOrDefault);
+ }
+
+
+ /// Determines whether the specified object is equal to this instance.
+ /// The object to compare with this instance.
+ /// true if the specified object is equal to this instance; otherwise, false.
+ public override bool Equals(object? obj)
+ {
+ return obj is Result other && Equals(other);
+ }
+
+ /// Returns the hash code for this instance.
+ /// A 32-bit signed integer hash code.
+ public override int GetHashCode()
+ {
+ return HashCode.Combine(_errors, _valueOrDefault);
+ }
+
+ /// Determines whether two instances are equal.
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the specified instances are equal; otherwise, false.
+ public static bool operator ==(Result left, Result right)
+ {
+ return left.Equals(right);
+ }
+
+ /// Determines whether two instances are not equal.
+ /// The first instance to compare.
+ /// The second instance to compare.
+ /// true if the specified instances are not equal; otherwise, false.
+ public static bool operator !=(Result left, Result right)
+ {
+ return !left.Equals(right);
+ }
+}
diff --git a/tools/LightResults.ComparisonBenchmarks/Benchmarks.cs b/tools/LightResults.ComparisonBenchmarks/Benchmarks.cs
index c93fcec..394c381 100644
--- a/tools/LightResults.ComparisonBenchmarks/Benchmarks.cs
+++ b/tools/LightResults.ComparisonBenchmarks/Benchmarks.cs
@@ -7,7 +7,7 @@ namespace LightResults.ComparisonBenchmarks;
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net80)]
-[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.RatioSD, Column.Gen0, Column.Gen1, Column.Gen2)]
+[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.Median, Column.RatioSD, Column.Gen0, Column.Gen1, Column.Gen2)]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public partial class Benchmarks
@@ -17,4 +17,4 @@ public partial class Benchmarks
private const int ResultValue = 0;
private const string ErrorMessage = "An unknown error occured.";
-}
+}
\ No newline at end of file
diff --git a/tools/LightResults.CurrentBenchmarks/Benchmarks.cs b/tools/LightResults.CurrentBenchmarks/Benchmarks.cs
index 7f2a1dd..5cff6c0 100644
--- a/tools/LightResults.CurrentBenchmarks/Benchmarks.cs
+++ b/tools/LightResults.CurrentBenchmarks/Benchmarks.cs
@@ -6,7 +6,7 @@ namespace LightResults.CurrentBenchmarks;
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net80)]
-[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.Gen0, Column.Gen1, Column.Gen2)]
+[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.Median, Column.Gen0, Column.Gen1, Column.Gen2)]
public class Benchmarks
{
[Params(100_000)]
@@ -73,7 +73,7 @@ public void Current_Result_HasError()
}
[Benchmark]
- public void Current_Result_ErrorsIndexer()
+ public void Current_Result_Error()
{
for (var iteration = 0; iteration < Iterations; iteration++)
_ = ResultFailWithErrorMessage.Error;
diff --git a/tools/LightResults.DevelopBenchmarks/Benchmarks.cs b/tools/LightResults.DevelopBenchmarks/Benchmarks.cs
index a2b588d..2229889 100644
--- a/tools/LightResults.DevelopBenchmarks/Benchmarks.cs
+++ b/tools/LightResults.DevelopBenchmarks/Benchmarks.cs
@@ -6,7 +6,7 @@ namespace LightResults.DevelopBenchmarks;
[MemoryDiagnoser]
[SimpleJob(RuntimeMoniker.Net80)]
-[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.Gen0, Column.Gen1, Column.Gen2)]
+[HideColumns(Column.Job, Column.Iterations, Column.Error, Column.StdDev, Column.Median, Column.Gen0, Column.Gen1, Column.Gen2)]
public class Benchmarks
{
[Params(100_000)]