From efa840b074e69b8c5a13efb66257b7f369efd236 Mon Sep 17 00:00:00 2001 From: Markus Iorio Date: Wed, 16 Oct 2024 14:03:08 +0200 Subject: [PATCH 1/4] Fix culture in tests for compatibility - Set current culture to "en-US" to ensure double parsing works outside of the US. --- src/RustyOptions.Tests/OptionParseTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/RustyOptions.Tests/OptionParseTests.cs b/src/RustyOptions.Tests/OptionParseTests.cs index 174c4c0..8444160 100644 --- a/src/RustyOptions.Tests/OptionParseTests.cs +++ b/src/RustyOptions.Tests/OptionParseTests.cs @@ -1,11 +1,17 @@ #if NET7_0_OR_GREATER using static RustyOptions.Option; +using System.Globalization; namespace RustyOptions.Tests { public class OptionParseTests { + public OptionParseTests() + { + CultureInfo.CurrentCulture = new CultureInfo("en-US"); + } + [Fact] public void CanParseStrings() { From c07d54db91f464cc39dd28af903acb8df9f3f3cf Mon Sep 17 00:00:00 2001 From: Markus Iorio Date: Wed, 16 Oct 2024 14:23:30 +0200 Subject: [PATCH 2/4] Implemented IsOkAnd to evaluate Ok state with a predicate and return corresponding value. --- src/RustyOptions/Result{T,TErr}.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/RustyOptions/Result{T,TErr}.cs b/src/RustyOptions/Result{T,TErr}.cs index e10c490..3449011 100644 --- a/src/RustyOptions/Result{T,TErr}.cs +++ b/src/RustyOptions/Result{T,TErr}.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -544,4 +544,20 @@ public int CompareTo(Result other) /// true if the parameter is less than or equal to the parameter. public static bool operator <=(Result left, Result right) => left.CompareTo(right) <= 0; + + /// + /// Checks whether the result is Ok and applies the given + /// to the value if it is. Returns true if both conditions are met; otherwise, returns false. + /// The resulting value is output through the parameter, which will be null + /// if the result is not Ok. + /// + /// The function to evaluate the value when the result is Ok. + /// When this method returns, contains the value if the result is Ok; otherwise, null. + /// true if the result is Ok and the predicate returns true; otherwise, false. + public bool IsOkAnd(Func predicate, [MaybeNullWhen(false)] out T value) + { + value = _value; + return predicate != null && _isOk && predicate(_value); + } + } From 0640d44a5f7171aeae6be02d536a91ed6217a434 Mon Sep 17 00:00:00 2001 From: Markus Iorio Date: Wed, 16 Oct 2024 14:24:08 +0200 Subject: [PATCH 3/4] Implemented IsErrAnd to evaluate Err state with a predicate and return corresponding error value. --- src/RustyOptions/Result{T,TErr}.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/RustyOptions/Result{T,TErr}.cs b/src/RustyOptions/Result{T,TErr}.cs index 3449011..6a691be 100644 --- a/src/RustyOptions/Result{T,TErr}.cs +++ b/src/RustyOptions/Result{T,TErr}.cs @@ -1,4 +1,4 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -560,4 +560,19 @@ public bool IsOkAnd(Func predicate, [MaybeNullWhen(false)] out T value) return predicate != null && _isOk && predicate(_value); } + /// + /// Checks whether the result is Err and applies the given + /// to the error value if it is. Returns true if both conditions are met; otherwise, returns false. + /// The resulting error value is output through the parameter, which will be null + /// if the result is not Err. + /// + /// The function to evaluate the error value when the result is Err. + /// When this method returns, contains the error value if the result is Err; otherwise, null. + /// true if the result is Err and the predicate returns true; otherwise, false. + public bool IsErrAnd(Func predicate, [MaybeNullWhen(false)] out TErr error) + { + error = _err; + return predicate != null && !_isOk && predicate(_err); + } + } From 2446033ca9b2238301008a14d67af9197ffa2a4a Mon Sep 17 00:00:00 2001 From: Markus Iorio Date: Wed, 16 Oct 2024 14:26:45 +0200 Subject: [PATCH 4/4] Added unit tests for IsOkAnd and IsErrAnd to verify correct predicate evaluation and result states. --- src/RustyOptions.Tests/ResultTests.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/RustyOptions.Tests/ResultTests.cs b/src/RustyOptions.Tests/ResultTests.cs index 9d15f8d..de55285 100644 --- a/src/RustyOptions.Tests/ResultTests.cs +++ b/src/RustyOptions.Tests/ResultTests.cs @@ -15,10 +15,15 @@ public void CanPerformBasicOperationsStructClass() var errStr2 = Err("Whoops!"); Assert.True(okInt.IsOk(out var o1) && o1 == 42); + Assert.True(okInt.IsOkAnd(n => n == 42, out _)); Assert.True(errStr.IsErr(out var e1) && e1 == "Whoops!"); + Assert.True(errStr.IsErrAnd(s => s == "Whoops!", out _)); Assert.False(okInt.IsErr(out _)); Assert.False(errStr.IsOk(out _)); + Assert.False(okInt.IsOkAnd(null, out _)); + Assert.False(errStr.IsOkAnd(null, out _)); + Assert.True(okInt == okInt2); Assert.Equal(okInt, okInt2); Assert.True(okInt.Equals((object)okInt2)); @@ -38,7 +43,10 @@ public void CanPerformBasicOperationsClassStruct() var errInt2 = Err(-1); Assert.True(okStr.IsOk(out var o1) && o1 == "Foo"); + Assert.True(okStr.IsOkAnd(s => s == "Foo", out _)); + Assert.True(errInt.IsErr(out var e1) && e1 == -1); + Assert.True(errInt.IsErrAnd(n => n == -1, out _)); Assert.False(okStr.IsErr(out _)); Assert.False(errInt.IsOk(out _)); @@ -58,7 +66,9 @@ public void CanCreateWithStringErr() var err = Err("oops"); Assert.True(ok.IsOk(out var okVal) && okVal == 42); + Assert.True(ok.IsOkAnd(n => n == 42, out _)); Assert.True(err.IsErr(out var errVal) && errVal == "oops"); + Assert.True(err.IsErrAnd(err => err == "oops", out _)); } [Fact] @@ -68,7 +78,9 @@ public void CanCreateWithExceptionErr() var err = Err(new InvalidOperationException("oops")); Assert.True(ok.IsOk(out var okVal) && okVal == 42); + Assert.True(ok.IsOkAnd(n => n == 42, out _)); Assert.True(err.IsErr(out var ex) && ex?.Message == "oops"); + Assert.True(err.IsErrAnd(exc => exc.Message == "oops", out _)); } [Fact] @@ -187,7 +199,9 @@ public void CanTry() int DoesNotThrow() => new[] { 42 }[0]; Assert.True(Result.Try(Throws).IsErr(out var ex) && ex is IndexOutOfRangeException); + Assert.True(Result.Try(Throws).IsErrAnd(exc => exc is IndexOutOfRangeException, out _)); Assert.True(Result.Try(DoesNotThrow).IsOk(out var val) && val == 42); + Assert.True(Result.Try(DoesNotThrow).IsOkAnd(n => n == 42, out _)); } [Fact]