diff --git a/CSharpFunctionalExtensions.Tests/MaybeTests/BasicTests.cs b/CSharpFunctionalExtensions.Tests/MaybeTests/BasicTests.cs index 37696ca8..4107bc2a 100644 --- a/CSharpFunctionalExtensions.Tests/MaybeTests/BasicTests.cs +++ b/CSharpFunctionalExtensions.Tests/MaybeTests/BasicTests.cs @@ -174,6 +174,50 @@ public void Maybe_None_doesnt_throw_on_Deconstruct() act.Should().NotThrow(); } + [Fact] + public void TryGetValue_returns_false_if_source_is_empty() + { + var maybe = Maybe.None; + + bool result = maybe.TryGetValue(out int value); + + result.Should().BeFalse(); + value.Should().Be(default); + } + + [Fact] + public void TryGetValue_returns_true_if_source_has_value() + { + var maybe = Maybe.From(5); + + bool result = maybe.TryGetValue(out int value); + + result.Should().BeTrue(); + value.Should().Be(5); + } + + [Fact] + public void TryGetValue_returns_false_if_source_is_empty_and_out_parameter_is_null() + { + var maybe = Maybe.None; + + bool result = maybe.TryGetValue(out int? value); + + result.Should().BeFalse(); + value.Should().BeNull(); + } + + [Fact] + public void TryGetValue_returns_true_if_source_has_value_and_out_parameter_is_null() + { + var maybe = Maybe.From(5); + + bool result = maybe.TryGetValue(out int? value); + + result.Should().BeTrue(); + value.Should().Be(5); + } + [Fact] public void Maybe_struct_default_is_none() { diff --git a/CSharpFunctionalExtensions.Tests/ResultTests/Methods/TryGetTests.cs b/CSharpFunctionalExtensions.Tests/ResultTests/Methods/TryGetTests.cs new file mode 100644 index 00000000..d3df2e9c --- /dev/null +++ b/CSharpFunctionalExtensions.Tests/ResultTests/Methods/TryGetTests.cs @@ -0,0 +1,92 @@ +using System; + +using FluentAssertions; +using Xunit; + +namespace CSharpFunctionalExtensions.Tests.ResultTests.Methods +{ + public class TryGetTests + { + public const string ErrorMessage = "Error from result"; + + [Fact] + public void Simple_result_tryGetError_is_false_Success_value_expected() + { + Result result = Result.Success(ErrorMessage); + result.TryGetError(out string error).Should().BeFalse(); + error.Should().BeNull(); + } + + [Fact] + public void Simple_result_tryGetError_is_true_Failure_value_expected() + { + Result result = Result.Failure(ErrorMessage); + result.TryGetError(out string error).Should().BeTrue(); + error.Should().Be(ErrorMessage); + } + + [Fact] + public void Generic_result_tryGetError_is_false_Success_value_expected() + { + Result result = Result.Success("Success"); + result.TryGetError(out string error).Should().BeFalse(); + error.Should().BeNull(); + } + + [Fact] + public void Generic_result_tryGetError_is_true_Failure_value_expected() + { + Result result = Result.Failure(ErrorMessage); + result.TryGetError(out string error).Should().BeTrue(); + error.Should().Be(ErrorMessage); + } + + [Fact] + public void Generic_result_tryGetSuccess_is_false_Failure_value_expected() + { + Result result = Result.Failure(ErrorMessage); + result.TryGetValue(out string value).Should().BeFalse(); + value.Should().BeNull(); + } + + [Fact] + public void Generic_result_tryGetSuccess_is_true_Success_value_expected() + { + Result result = Result.Success("Success"); + result.TryGetValue(out string value).Should().BeTrue(); + value.Should().Be("Success"); + } + + [Fact] + public void Value_Error_Generic_result_tryGetError_is_false_Success_value_expected() + { + Result result = Result.Success("Success"); + result.TryGetError(out string error).Should().BeFalse(); + error.Should().BeNull(); + } + + [Fact] + public void Value_Error_Generic_result_tryGetError_is_true_Failure_value_expected() + { + Result result = Result.Failure(ErrorMessage); + result.TryGetError(out string error).Should().BeTrue(); + error.Should().Be(ErrorMessage); + } + + [Fact] + public void Value_Error_Generic_result_tryGetSuccess_is_false_Failure_value_expected() + { + Result result = Result.Failure(ErrorMessage); + result.TryGetValue(out string value).Should().BeFalse(); + value.Should().BeNull(); + } + + [Fact] + public void Value_Error_Generic_result_tryGetSuccess_is_true_Success_value_expected() + { + Result result = Result.Success("Success"); + result.TryGetValue(out string value).Should().BeTrue(); + value.Should().Be("Success"); + } + } +} \ No newline at end of file diff --git a/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj b/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj index 1096c335..6d4c84a3 100644 --- a/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj +++ b/CSharpFunctionalExtensions/CSharpFunctionalExtensions.csproj @@ -45,7 +45,7 @@ - + all @@ -53,7 +53,7 @@ - + diff --git a/CSharpFunctionalExtensions/Maybe/Maybe.cs b/CSharpFunctionalExtensions/Maybe/Maybe.cs index e4abe86d..aef93f33 100644 --- a/CSharpFunctionalExtensions/Maybe/Maybe.cs +++ b/CSharpFunctionalExtensions/Maybe/Maybe.cs @@ -1,5 +1,11 @@ using System; using System.Collections.Generic; +#if NETCORE || NETSTANDARD || NET45_OR_GREATER +using System.Runtime.CompilerServices; +#endif +#if NET_5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif namespace CSharpFunctionalExtensions { @@ -29,6 +35,23 @@ public T GetValueOrDefault(T defaultValue = default) return _value; } + + /// + /// Indicates whether the inner value is present and returns the value if it is. + /// + /// The inner value, if present; otherwise `default` +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetValue( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out T value) + { + value = _value; + return _isValueSet; + } /// /// Try to use GetValueOrThrow() or GetValueOrDefault() instead for better explicitness. @@ -160,7 +183,7 @@ public readonly struct Maybe /// /// Useful in scenarios where you need to determine if a value is Maybe or not /// - public interface IMaybe + public interface IMaybe { T Value { get; } bool HasValue { get; } diff --git a/CSharpFunctionalExtensions/Result/Methods/TryGet.cs b/CSharpFunctionalExtensions/Result/Methods/TryGet.cs new file mode 100644 index 00000000..a689078b --- /dev/null +++ b/CSharpFunctionalExtensions/Result/Methods/TryGet.cs @@ -0,0 +1,176 @@ +#if NETCORE || NETSTANDARD || NET45_OR_GREATER +using System.Runtime.CompilerServices; +#endif +#if NET_5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif + +namespace CSharpFunctionalExtensions +{ + partial struct Result + { +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out string error) + { + error = _error; + return IsFailure; + } + } + + partial struct Result + { +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetValue( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out T value) + { + value = _value; + return IsSuccess; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out string error) + { + error = _error; + return IsFailure; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetValue( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out T value, +#if NET_5_0_OR_GREATER + [NotNullWhen(false), MaybeNullWhen(true)] +#endif + out string error + ) + { + value = _value; + error = _error; + return IsSuccess; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out string error, +#if NET_5_0_OR_GREATER + [NotNullWhen(false), MaybeNullWhen(true)] +#endif + out T value + ) + { + value = _value; + error = _error; + return IsFailure; + } + } + + partial struct Result + { + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetValue( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out T value) + { + value = _value; + return IsSuccess; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out E error) + { + error = _error; + return IsFailure; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetValue( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out T value, +#if NET_5_0_OR_GREATER + [NotNullWhen(false), MaybeNullWhen(true)] +#endif + out E error + ) + { + value = _value; + error = _error; + return IsSuccess; + } + +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out E error, +#if NET_5_0_OR_GREATER + [NotNullWhen(false), MaybeNullWhen(true)] +#endif + out T value + ) + { + value = _value; + error = _error; + return IsFailure; + } + } + + partial struct UnitResult + { +#if NETCORE || NETSTANDARD || NET45_OR_GREATER + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif + public bool TryGetError( +#if NET_5_0_OR_GREATER + [NotNullWhen(true), MaybeNullWhen(false)] +#endif + out E error) + { + error = _error; + return IsFailure; + } + } +} \ No newline at end of file