Skip to content

Commit

Permalink
0.1.3 (#2)
Browse files Browse the repository at this point in the history
* Add Fallible.Void type to specify a return type which returns nothing but can contain an error.

Fallible.Void can only be created using the Fallible.Return property.

* Add Fallible.Void type to specify a return type which returns nothing but can contain an error.

Fallible.Void can only be created using the Fallible.Return property.
  • Loading branch information
tvandinther authored Mar 13, 2022
1 parent af1d600 commit 242feee
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 27 deletions.
23 changes: 22 additions & 1 deletion Fallible.Tests/FallibleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public void WhenCreated_ContainsError()

Assert.Equal(error, fallible.Error);
}

[Fact]
public void WhenCreated_ContainsDefaultValue_WhenValueType()
{
Expand Down Expand Up @@ -75,6 +75,16 @@ public void CanBeDeconstructed_ValueIsExpected()
Assert.Equal(expectedValue, value);
}

[Fact]
public void CanBeDeconstructed_ShouldHaveNullResult_WhenVoidReturn()
{
Fallible<Void> fallible = new Error("Wrong Number");

var (result, _) = fallible;

Assert.Null(result);
}

#endregion

#region Conversion Tests
Expand Down Expand Up @@ -123,6 +133,17 @@ public void CanBeImplicitlyConverted_FromTuple_WhenValueIsNull()
Assert.IsType<Fallible<object>>(fallible);
}

[Fact]
public void CanBeImplicitlyConverted_FromVoid_WhenReturning()
{
var func = Fallible<Void>() => Fallible.Return;

Fallible<Void> fallible = func();

Assert.IsType<Fallible<Void>>(fallible);

}

#endregion

#region Static Method Tests
Expand Down
2 changes: 1 addition & 1 deletion Fallible/Fallible.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageVersion>0.1.2</PackageVersion>
<PackageVersion>0.1.3</PackageVersion>
<Title>Fallible</Title>
<Authors>Tom van Dinther</Authors>
<Description>An idiomatic way to explicitly define, propagate and handle error states in C#. This library is inspired by Go's errors.</Description>
Expand Down
30 changes: 5 additions & 25 deletions Fallible/Fallible.cs → Fallible/FallibleGenericStruct.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Fallible;

#region Generic Struct

public readonly record struct Fallible<T> : IStructuralEquatable, ITuple
{
public T Value { get; }
Expand All @@ -17,7 +15,11 @@ private Fallible(T value, Error error)
Error = error;
}

public static implicit operator Fallible<T>(Error error) => new(default!, error);
public static implicit operator Fallible<T>(Error error)
{
return new(default!, error);
}

public static implicit operator Fallible<T>(T value) => new(value, default!);
public static implicit operator Fallible<T>((T? value, Error? error) tuple) => new(tuple.value!, tuple.error!);

Expand Down Expand Up @@ -49,25 +51,3 @@ public int GetHashCode(IEqualityComparer comparer)

public int Length => 2;
}

#endregion

#region Static Class

public static class Fallible
{
public static Fallible<TResult> Try<TResult>(Func<TResult> action, [CallerArgumentExpression("action")] string expression = "")
{
try
{
var value = action();
return value;
}
catch (Exception e)
{
return new Error($"{expression} threw {e.GetType().Name}: {e.Message}");
}
}
}

#endregion
21 changes: 21 additions & 0 deletions Fallible/FallibleStatic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Runtime.CompilerServices;

namespace Fallible;

public static class Fallible
{
public static Fallible<TResult> Try<TResult>(Func<TResult> action, [CallerArgumentExpression("action")] string expression = "")
{
try
{
var value = action();
return value;
}
catch (Exception e)
{
return new Error($"{expression} threw {e.GetType().Name}: {e.Message}");
}
}

public static Fallible<Void> Return => new Void();
}
6 changes: 6 additions & 0 deletions Fallible/Void.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Fallible;

public class Void
{
internal Void() { }
}
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ public Fallible<int> GetValue(int arg)
}
```

#### Returning `void`

Fallible includes a `void` type that can be used to return *void* from a method. It does not have an accessible constructor and can only be created by using the `Fallible.Return` property.

```c#
public Fallible<Void> DoSomething()
{
// Do something
if (somethingFailed) return new Error("Something went wrong");

return Fallible.Return;
}
```

### Working with `Fallible<T>`

When working with a `Fallible<T>` type returned by a method, it is best to deconstruct it upon assignment and then perform a check on the error state. `Error` contains an implicit boolean conversion operator that returns `true` if the error state is not `null`.
Expand Down

0 comments on commit 242feee

Please sign in to comment.