Skip to content

Commit

Permalink
BREAK: ToResult renamed to MapToResult for consinstency
Browse files Browse the repository at this point in the history
  • Loading branch information
MrBogomips committed Dec 9, 2024
1 parent 6ccfc39 commit 98bcc88
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 23 deletions.
6 changes: 6 additions & 0 deletions src/Monads/Error/MaybeNoneError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Bogoware.Monads;

public class MaybeNoneError(string message) : LogicError(message)
{
public static readonly MaybeNoneError Default = new("The maybe is none.");
}
3 changes: 1 addition & 2 deletions src/Monads/Error/RuntimeError.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ public sealed class RuntimeError : Error
public Exception Exception { get; }
public RuntimeError(Exception exception)
{
if (exception is null) throw new ArgumentNullException(nameof(exception));
Exception = exception;
Exception = exception ?? throw new ArgumentNullException(nameof(exception));
}

public override string Message => Exception.Message;
Expand Down
3 changes: 3 additions & 0 deletions src/Monads/Maybe/Maybe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ public Maybe(TValue? value)
/// </summary>
public Maybe<TNewValue> Map<TNewValue>(Func<TValue, TNewValue?> map) where TNewValue : class
=> Value is not null ? new Maybe<TNewValue>(map(Value)) : Maybe<TNewValue>.None;

public Result<TValue> MapToResult() =>
Value is not null ? Result.Success(Value) : Result.Failure<TValue>(MaybeNoneError.Default);

/// <inheritdoc cref="M:Bogoware.Monads.Maybe`1.Map``1(System.Func{`0,``0})"/>
public async Task<Maybe<TNewValue>> Map<TNewValue>(Func<TValue, Task<TNewValue?>> map) where TNewValue : class
Expand Down
4 changes: 2 additions & 2 deletions src/Monads/Maybe/MaybeAsyncExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,14 @@ public static Task<bool> Satisfy<TValue>(this Task<Maybe<TValue>> maybe, Func<TV
public static async Task<Result<TValue>> ToResult<TValue>(this Task<Maybe<TValue>> maybeTask, Func<Error> errorFunc) where TValue : class
{
var maybe = await maybeTask;
return maybe.ToResult(errorFunc);
return maybe.MapToResult(errorFunc);
}

/// <inheritdoc cref="M:Bogoware.Monads.MaybeExtensions.ToResult``1(Bogoware.Monads.Maybe{``0},System.Func{Bogoware.Monads.Error})"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Result<TValue>> ToResult<TValue>(this Task<Maybe<TValue>> maybeTask, Func<Task<Error>> errorFunc) where TValue : class
{
var maybe = await maybeTask;
return await maybe.ToResult(errorFunc);
return await maybe.MapToResult(errorFunc);
}
}
64 changes: 50 additions & 14 deletions src/Monads/Maybe/MaybeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ public static Maybe<TNewValue> Map<TValue, TNewValue>(this Maybe<TValue> maybe,

/// <inheritdoc cref="Map{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult)"/>
public static async Task<Maybe<TNewValue>> Map<TValue, TNewValue>(
this Maybe<TValue> maybe, Func<Task<TNewValue?>> map)
this Maybe<TValue> maybe,
Func<Task<TNewValue?>> map
)
where TNewValue : class where TValue : class
=> maybe.IsSome ? new(await map()) : Maybe<TNewValue>.None;

Expand All @@ -35,7 +37,9 @@ public static Maybe<TNewValue> Bind<TValue, TNewValue>(this Maybe<TValue> maybe,

/// <inheritdoc cref="Bind{TValue,TResult}(Bogoware.Monads.Maybe{TValue},System.Func{Bogoware.Monads.Maybe{TResult}})"/>
public static Task<Maybe<TNewValue>> Bind<TValue, TNewValue>(
this Maybe<TValue> maybe, Func<Task<Maybe<TNewValue>>> map)
this Maybe<TValue> maybe,
Func<Task<Maybe<TNewValue>>> map
)
where TNewValue : class where TValue : class
=> maybe.IsSome ? map() : Task.FromResult(Maybe<TNewValue>.None);

Expand All @@ -48,37 +52,55 @@ public static TResult Match<TValue, TResult>(this Maybe<TValue> maybe, TResult r

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static TResult Match<TValue, TResult>(
this Maybe<TValue> maybe, Func<TResult> resultOnValue, TResult resultOnNone)
this Maybe<TValue> maybe,
Func<TResult> resultOnValue,
TResult resultOnNone
)
where TValue : class
=> maybe.IsSome ? resultOnValue() : resultOnNone;

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static TResult Match<TValue, TResult>(
this Maybe<TValue> maybe, TResult resultOnValue, Func<TResult> resultOnNone)
this Maybe<TValue> maybe,
TResult resultOnValue,
Func<TResult> resultOnNone
)
where TValue : class
=> maybe.IsSome ? resultOnValue : resultOnNone();

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static TResult Match<TValue, TResult>(
this Maybe<TValue> maybe, Func<TResult> resultOnValue, Func<TResult> resultOnNone)
this Maybe<TValue> maybe,
Func<TResult> resultOnValue,
Func<TResult> resultOnNone
)
where TValue : class
=> maybe.IsSome ? resultOnValue() : resultOnNone();

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static Task<TResult> Match<TValue, TResult>(
this Maybe<TValue> maybe, Func<Task<TResult>> resultOnValue, TResult resultOnNone)
this Maybe<TValue> maybe,
Func<Task<TResult>> resultOnValue,
TResult resultOnNone
)
where TValue : class
=> maybe.IsSome ? resultOnValue() : Task.FromResult(resultOnNone);

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static Task<TResult> Match<TValue, TResult>(
this Maybe<TValue> maybe, TResult resultOnValue, Func<Task<TResult>> resultOnNone)
this Maybe<TValue> maybe,
TResult resultOnValue,
Func<Task<TResult>> resultOnNone
)
where TValue : class
=> maybe.IsSome ? Task.FromResult(resultOnValue) : resultOnNone();

/// <inheritdoc cref="Match{TValue,TResult}(Bogoware.Monads.Maybe{TValue},TResult,TResult)"/>
public static Task<TResult> Match<TValue, TResult>(
this Maybe<TValue> maybe, Func<Task<TResult>> resultOnValue, Func<Task<TResult>> resultOnNone)
this Maybe<TValue> maybe,
Func<Task<TResult>> resultOnValue,
Func<Task<TResult>> resultOnNone
)
where TValue : class
=> maybe.IsSome ? resultOnValue() : resultOnNone();

Expand Down Expand Up @@ -198,26 +220,40 @@ public static Maybe<TNewValue> WithDefault<TNewValue>(this Maybe<TNewValue> mayb
/// <inheritdoc cref="WithDefault{T}(Bogoware.Monads.Maybe{T},T)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static async Task<Maybe<TNewValue>> WithDefault<TNewValue>(
this Maybe<TNewValue> maybe, Func<Task<TNewValue>> value) where TNewValue : class
this Maybe<TNewValue> maybe,
Func<Task<TNewValue>> value
) where TNewValue : class
=> maybe.IsSome ? maybe : new(await value());

/// <summary>
/// Convert a <see cref="Maybe{T}"/> to a <see cref="Result{TValue}"/> with a default error in case of <c>None</c>.
/// </summary>
/// <param name="maybe"></param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Result<TValue> ToResult<TValue>(this Maybe<TValue> maybe, Func<Error> errorFunc)
public static Result<TValue> MapToResult<TValue>(this Maybe<TValue> maybe)
where TValue : class
=> maybe.Match(
value => Result.Success(value),
Result.Success,
() => Result.Failure<TValue>(MaybeNoneError.Default)
);

/// <summary>
/// Convert a <see cref="Maybe{T}"/> to a <see cref="Result{TValue}"/> with a default error in case of <c>None</c>.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Result<TValue> MapToResult<TValue>(this Maybe<TValue> maybe, Func<Error> errorFunc)
where TValue : class
=> maybe.Match(
Result.Success,
() => Result.Failure<TValue>(errorFunc())
);

/// <inheritdoc cref="M:Bogoware.Monads.MaybeExtensions.ToResult``1(Bogoware.Monads.Maybe{``0},System.Func{Bogoware.Monads.Error})"/>
/// <inheritdoc cref="M:Bogoware.Monads.MaybeExtensions.MapToResult``1(Bogoware.Monads.Maybe{``0},System.Func{Bogoware.Monads.Error})"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Task<Result<TValue>> ToResult<TValue>(this Maybe<TValue> maybe, Func<Task<Error>> errorFunc)
public static Task<Result<TValue>> MapToResult<TValue>(this Maybe<TValue> maybe, Func<Task<Error>> errorFunc)
where TValue : class
=> maybe.Match(
value => Result.Success(value),
Result.Success,
async () => Result.Failure<TValue>(await errorFunc())
);
}
32 changes: 27 additions & 5 deletions test/Monads.UnitTests/MaybeTests/MaybeToResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,40 @@ public void Some_ToResult_ShouldReturnAnError()
{
var sut = Maybe.Some<string>("SomeValue");

var actual = sut.ToResult(() => new LogicError("Not Found"));
var actual = sut.MapToResult();

actual.IsSuccess.Should().BeTrue();
actual.GetValueOrThrow().Should().Be("SomeValue");
}

[Fact]
public void None_ToResult_ShouldReturnAnError()
{
var sut = Maybe.None<string>();

var actual = sut.ToResult(() => new LogicError("Not Found"));
var actual = sut.MapToResult();

actual.IsFailure.Should().BeTrue();
actual.GetErrorOrThrow().Should().BeOfType<MaybeNoneError>();
}

[Fact]
public void Some_ToResultWithError_ShouldReturnAnError()
{
var sut = Maybe.Some<string>("SomeValue");

var actual = sut.MapToResult(() => new LogicError("Not Found"));

actual.IsSuccess.Should().BeTrue();
actual.GetValueOrThrow().Should().Be("SomeValue");
}

[Fact]
public void None_ToResultWithError_ShouldReturnAnError()
{
var sut = Maybe.None<string>();

var actual = sut.MapToResult(() => new LogicError("Not Found"));

actual.IsFailure.Should().BeTrue();
}
Expand All @@ -29,7 +51,7 @@ public async Task Some_ToResult_ShouldReturnAnError_withAsync()
var sut = Maybe.Some<string>("SomeValue");
var errorFunc = new Func<Task<Error>>(() => Task.FromResult<Error>(new LogicError("Not Found")));

var actual = await sut.ToResult(errorFunc);
var actual = await sut.MapToResult(errorFunc);

actual.IsSuccess.Should().BeTrue();
actual.GetValueOrThrow().Should().Be("SomeValue");
Expand All @@ -41,7 +63,7 @@ public async Task None_ToResult_ShouldReturnAnError_withAsync()
var sut = Maybe.None<string>();
var errorFunc = new Func<Task<Error>>(() => Task.FromResult<Error>(new LogicError("Not Found")));

var actual = await sut.ToResult(errorFunc);
var actual = await sut.MapToResult(errorFunc);

actual.IsFailure.Should().BeTrue();
}
Expand Down

0 comments on commit 98bcc88

Please sign in to comment.