From 4dc9c4ede25ab5fb2881044a6471b9609fab9d6a Mon Sep 17 00:00:00 2001 From: Tomohisa Takaoka <ttakaoka@jtechs.com> Date: Fri, 9 Aug 2024 17:57:32 -0700 Subject: [PATCH] Add OptionalValue.FromNullableValue --- .../ResultBoxes.Test/ConveyorSpec.cs | 4 +-- src/ResultBoxes/ResultBoxes.Test/UnitTest1.cs | 28 +++++++++++++++++++ src/ResultBoxes/ResultBoxes/OptionalValue.cs | 19 +++++++------ .../ResultBoxes/ResultBoxes.csproj | 6 ++-- src/Samples/ConsoleApp2Optional/Program.cs | 2 +- 5 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/ResultBoxes/ResultBoxes.Test/ConveyorSpec.cs b/src/ResultBoxes/ResultBoxes.Test/ConveyorSpec.cs index f039e8a..a40a016 100644 --- a/src/ResultBoxes/ResultBoxes.Test/ConveyorSpec.cs +++ b/src/ResultBoxes/ResultBoxes.Test/ConveyorSpec.cs @@ -2,10 +2,8 @@ namespace ResultBoxes.Test; -public class ConveyorSpec(ITestOutputHelper testOutputHelper) +public class ConveyorSpec() { - - [Fact] public void ConveyorWithNoParam() { diff --git a/src/ResultBoxes/ResultBoxes.Test/UnitTest1.cs b/src/ResultBoxes/ResultBoxes.Test/UnitTest1.cs index 3a225d3..bd931d3 100644 --- a/src/ResultBoxes/ResultBoxes.Test/UnitTest1.cs +++ b/src/ResultBoxes/ResultBoxes.Test/UnitTest1.cs @@ -101,3 +101,31 @@ public async Task Railway3AsyncSpec() Assert.Equal(12, sut.GetValue()); } } + +public class OptionalValueTests +{ + [Fact] + public void OptionalValueEmptyTest() + { + var sut = OptionalValue<string>.Empty; + + Assert.False(sut.HasValue); + Assert.Throws<ResultsInvalidOperationException>(() => sut.GetValue()); + } + + [Fact] + public void OptionalValueCreateSpec() + { + var value = (Guid?) Guid.NewGuid(); + var sut = OptionalValue.FromNullableValue(value); + Assert.True(sut.HasValue); + } + [Fact] + public void OptionalValueCreateSpec2() + { + var value = (Guid?) null; + var sut = OptionalValue.FromNullableValue(value); + Assert.False(sut.HasValue); + } + +} \ No newline at end of file diff --git a/src/ResultBoxes/ResultBoxes/OptionalValue.cs b/src/ResultBoxes/ResultBoxes/OptionalValue.cs index 5182d2b..956ed00 100644 --- a/src/ResultBoxes/ResultBoxes/OptionalValue.cs +++ b/src/ResultBoxes/ResultBoxes/OptionalValue.cs @@ -1,14 +1,17 @@ using System.Text.Json.Serialization; namespace ResultBoxes; -public record OptionalValue<TValue>(TValue? Value) +public record OptionalValue<TValue>(TValue? Value, bool HasValue = true) { - [JsonIgnore] - public bool HasValue => Value is not null; - - public static OptionalValue<TValue> Empty => new(default); - public static OptionalValue<TValue> Null => new(default); - public TValue GetValue() => Value ?? throw new ResultsInvalidOperationException("no value"); + public static OptionalValue<TValue> Empty => new(default, false); + public static OptionalValue<TValue> Null => new(default, false); + public TValue GetValue() => HasValue && Value is not null ? Value : throw new ResultsInvalidOperationException("no value"); public static implicit operator OptionalValue<TValue>(TValue value) => new(value); - public static OptionalValue<TValue> FromValue(TValue value) => new(value); +} +public static class OptionalValue +{ + public static OptionalValue<TValue> FromValue<TValue>(TValue value) where TValue : notnull => new(value); + public static OptionalValue<TValue> FromNullableValue<TValue>(TValue? value) where TValue : notnull => value is null ? OptionalValue<TValue>.Null : new(value); + public static OptionalValue<TValue> FromNullableValue<TValue>(TValue? value) where TValue : struct => value.HasValue ? new(value.Value) : OptionalValue<TValue>.Null; + public static ResultBox<TValue> GetValueResult<TValue>(this OptionalValue<TValue> optional) where TValue : notnull => optional.HasValue && optional.Value is not null ? optional.Value : new ResultsInvalidOperationException("no value"); } diff --git a/src/ResultBoxes/ResultBoxes/ResultBoxes.csproj b/src/ResultBoxes/ResultBoxes/ResultBoxes.csproj index be6e615..841b2e0 100644 --- a/src/ResultBoxes/ResultBoxes/ResultBoxes.csproj +++ b/src/ResultBoxes/ResultBoxes/ResultBoxes.csproj @@ -7,13 +7,13 @@ <RootNamespace>ResultBoxes</RootNamespace> <LangVersion>preview</LangVersion> <PackageId>ResultBoxes</PackageId> - <Version>0.3.21</Version> + <Version>0.3.22</Version> <Authors>J-Tech Group</Authors> <Company>J-Tech-Japan</Company> <PackageDescription>ResultBoxes - C# Results Library that focus on Railway Programming.</PackageDescription> <RepositoryUrl>https://github.com/J-Tech-Japan/ResultBoxes</RepositoryUrl> - <PackageVersion>0.3.21</PackageVersion> - <Description>CheckNullWrapTry - CheckNull exception go through exceptionMapper</Description> + <PackageVersion>0.3.22</PackageVersion> + <Description>Adding OptionalValue.FromNullableValue</Description> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <PackageReadmeFile>README.md</PackageReadmeFile> <IncludeSymbols>true</IncludeSymbols> diff --git a/src/Samples/ConsoleApp2Optional/Program.cs b/src/Samples/ConsoleApp2Optional/Program.cs index 2ce1b21..2a99fe4 100644 --- a/src/Samples/ConsoleApp2Optional/Program.cs +++ b/src/Samples/ConsoleApp2Optional/Program.cs @@ -8,7 +8,7 @@ public static ResultBox<OptionalValue<string>> ConvertStringToHalfLength(string { 0 => new ApplicationException("Input string is empty"), // Exception 1 => OptionalValue<string>.Empty, // Not error but Empty - _ => OptionalValue<string>.FromValue(input[..^(input.Length / 2)]) // has value + _ => OptionalValue.FromValue(input[..^(input.Length / 2)]) // has value }; private static void Main(string[] args) {