Skip to content
4 changes: 3 additions & 1 deletion samples/FluentUtils.Monad.Samples/PersonFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ public static ResultType<Person> Create(string name)
{
// dynamically generated error code
return Result.Error<Person>(
"A name cannot be more than 255 characters long"
new Error(
"PF_01",
"A name cannot be more than 255 characters long")
);
}

Expand Down
8 changes: 7 additions & 1 deletion src/FluentUtils.Monad/Empty.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@
/// no value.
/// </summary>
[PublicAPI]
public readonly record struct Empty;
public readonly record struct Empty
{
/// <summary>
/// The default <see cref="Empty" /> value
/// </summary>
public static readonly Empty Default;
}
8 changes: 8 additions & 0 deletions src/FluentUtils.Monad/ErrorCode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ public readonly record struct ErrorCode(string Value)
/// <param name="value">The error code string</param>
/// <returns>The <see cref="ErrorCode" /> instance</returns>
public static implicit operator ErrorCode(string value) => new(value);

/// <summary>
/// Implicitly converts an <see cref="ErrorCode" /> to a string.
/// </summary>
/// <param name="errorCode">The error code.</param>
/// <returns>The error code string.</returns>
public static implicit operator string(ErrorCode errorCode) =>
errorCode.ToString();
}
7 changes: 7 additions & 0 deletions src/FluentUtils.Monad/ErrorMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,11 @@
/// <param name="value">The error message string</param>
/// <returns>The <see cref="ErrorMessage" /> instance</returns>
public static implicit operator ErrorMessage(string value) => new(value);

/// <summary>
/// Implicitly converts an <see cref="ErrorMessage" /> to a string.
/// </summary>
/// <param name="value">The error message.</param>
/// <returns>The string.</returns>
public static implicit operator string(ErrorMessage value) => value.Value;

Check warning on line 29 in src/FluentUtils.Monad/ErrorMessage.cs

View check run for this annotation

Codecov / codecov/patch

src/FluentUtils.Monad/ErrorMessage.cs#L29

Added line #L29 was not covered by tests
}
4 changes: 2 additions & 2 deletions src/FluentUtils.Monad/ErrorResultType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
public Error Error { get; }

/// <summary>
/// Converts a <see cref="ErrorResultType{T}" /> of type <see cref="T" /> to
/// Converts a <see cref="ErrorResultType{TOut}" /> of type T to
/// a type of <see cref="TOut" />, preserving the error inside the result

Check warning on line 29 in src/FluentUtils.Monad/ErrorResultType.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'TOut' that could not be resolved

Check warning on line 29 in src/FluentUtils.Monad/ErrorResultType.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'TOut' that could not be resolved

Check warning on line 29 in src/FluentUtils.Monad/ErrorResultType.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'TOut' that could not be resolved
/// </summary>
/// <typeparam name="TOut">The output type</typeparam>
/// <returns>A <see cref="ErrorResultType{T}" /> where T is the output type</returns>
/// <returns>A <see cref="ErrorResultType{TOut}" /> where T is the output type</returns>
public ResultType<TOut> To<TOut>() =>
new ErrorResultType<TOut>(Error);
}
13 changes: 6 additions & 7 deletions src/FluentUtils.Monad/Extensions/EnsureAsyncExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace FluentUtils.Monad.Extensions;

using System.Diagnostics;
using System.Runtime.CompilerServices;

/// <summary>
Expand All @@ -22,25 +23,23 @@ public static class EnsureAsyncExtensions
/// Optional. The <see cref="Error" /> that will be assigned to
/// the result if it does not pass the predicate
/// </param>
/// <param name="cancellationToken">The <see cref="CancellationToken" /></param>
/// <param name="predicateExpression">The predicate expression</param>
/// <typeparam name="T">The result value type</typeparam>
/// <returns>The original result on success, otherwise an error result</returns>
[DebuggerStepperBoundary]
public static Task<ResultType<T>> EnsureAsync<T>(
this Task<ResultType<T>> resultTask,
Func<T, CancellationToken, Task<bool>> predicate,
Func<T, Task<bool>> predicate,
Error? error = default,
CancellationToken cancellationToken = default,
[CallerArgumentExpression(nameof(predicate))]
string predicateExpression = "not provided") => resultTask.MatchAsync(
async (value, ct) =>
async value =>
{
bool passed = await predicate(value, ct);
bool passed = await predicate(value);

if (passed) return await resultTask;

return error ?? MonadErrors.FailedPredicate(predicateExpression);
},
Result.ErrorAsync<T>,
cancellationToken);
Result.ErrorAsync<T>);
}
2 changes: 2 additions & 0 deletions src/FluentUtils.Monad/Extensions/EnsureExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace FluentUtils.Monad.Extensions;

using System.Diagnostics;
using System.Runtime.CompilerServices;

/// <summary>
Expand All @@ -25,6 +26,7 @@ public static class EnsureExtensions
/// <param name="predicateExpression">The predicate expression</param>
/// <typeparam name="T">The result value type</typeparam>
/// <returns>The original result on success, otherwise an error result</returns>
[DebuggerStepperBoundary]
public static ResultType<T> Ensure<T>(
this ResultType<T> result,
Func<T, bool> predicate,
Expand Down
73 changes: 37 additions & 36 deletions src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace FluentUtils.Monad.Extensions;

using System.Diagnostics;

/// <summary>
/// Extensions for matching on an asynchronous <see cref="ResultType{T}" />
/// </summary>
Expand All @@ -8,8 +10,8 @@
{
/// <summary>
/// Performs a match on the <see cref="ResultType{T}" />, invoking the
/// <see cref="okHandler" /> for an <see cref="OkResultType{T}" />

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'okHandler' that could not be resolved
/// and the <see cref="errorHandler" /> for an

Check warning on line 14 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 14 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 14 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'errorHandler' that could not be resolved
/// <see cref="ErrorResultType{T}" />
/// </summary>
/// <param name="resultTask">The asynchronous <see cref="ResultType{T}" /></param>
Expand All @@ -21,7 +23,6 @@
/// The operation to perform for an
/// <see cref="ErrorResultType{T}" />
/// </param>
/// <param name="cancellationToken">The <see cref="CancellationToken" /></param>
/// <typeparam name="TIn">The input result value's type</typeparam>
/// <typeparam name="TOut">The output value's type</typeparam>
/// <returns>The output value from the invoked handler</returns>
Expand All @@ -30,31 +31,40 @@
/// <see cref="ResultType{T}" /> is not one of <see cref="OkResultType{T}" />
/// or <see cref="ErrorResultType{T}" />
/// </exception>
[DebuggerStepperBoundary]
public static async Task<TOut> MatchAsync<TIn, TOut>(
this Task<ResultType<TIn>> resultTask,
Func<TIn, CancellationToken, Task<TOut>> okHandler,
Func<Error, CancellationToken, Task<TOut>> errorHandler,
CancellationToken cancellationToken = default
Func<TIn, Task<TOut>> okHandler,
Func<Error, Task<TOut>> errorHandler
)
{
return await resultTask switch
{
OkResultType<TIn> ok => await okHandler(
ok.Value,
cancellationToken
),
ErrorResultType<TIn> err => await errorHandler(
err.Error,
cancellationToken
),
OkResultType<TIn> ok => await okHandler(ok.Value),
ErrorResultType<TIn> err => await errorHandler(err.Error),
var result => throw new UnsupportedResultTypeException<TIn>(result),
};
}

/// <summary>
/// </summary>
/// <param name="resultTask"></param>
/// <param name="okHandler"></param>
/// <param name="errorHandler"></param>
/// <typeparam name="TIn"></typeparam>
/// <typeparam name="TOut"></typeparam>
/// <returns></returns>
public static async Task<TOut> MatchAsync<TIn, TOut>(
this Task<ResultType<TIn>> resultTask,
Func<TIn, TOut> okHandler,
Func<Error, TOut> errorHandler) => await resultTask.MatchAsync(
value => Task.FromResult(okHandler(value)),
error => Task.FromResult(errorHandler(error)));

/// <summary>
/// Performs a match on the <see cref="ResultType{T}" />, invoking the
/// <see cref="okHandler" /> for an <see cref="OkResultType{T}" />

Check warning on line 66 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 66 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 66 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'okHandler' that could not be resolved
/// and the <see cref="errorHandler" /> for an

Check warning on line 67 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 67 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 67 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'errorHandler' that could not be resolved
/// <see cref="ErrorResultType{T}" />
/// </summary>
/// <param name="resultTask">The asynchronous <see cref="ResultType{T}" /></param>
Expand All @@ -66,7 +76,6 @@
/// The operation to perform for an
/// <see cref="ErrorResultType{T}" />
/// </param>
/// <param name="cancellationToken">The <see cref="CancellationToken" /></param>
/// <typeparam name="TOut">The output value's type</typeparam>
/// <returns>The output value from the invoked handler</returns>
/// <exception cref="UnsupportedResultTypeException{TIn}">
Expand All @@ -76,19 +85,17 @@
/// </exception>
public static async Task<TOut> MatchAsync<TOut>(
this Task<ResultType<Empty>> resultTask,
Func<CancellationToken, Task<TOut>> okHandler,
Func<Error, CancellationToken, Task<TOut>> errorHandler,
CancellationToken cancellationToken = default
Func<Task<TOut>> okHandler,
Func<Error, Task<TOut>> errorHandler
) => await resultTask.MatchAsync(
(_, token) => okHandler(token),
errorHandler,
cancellationToken
_ => okHandler(),
errorHandler
);

/// <summary>
/// Performs a match on the <see cref="ResultType{T}" />, invoking the
/// <see cref="okHandler" /> for an <see cref="OkResultType{T}" />

Check warning on line 97 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 97 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 97 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'okHandler' that could not be resolved
/// and the <see cref="errorHandler" /> for an

Check warning on line 98 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 98 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 98 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'errorHandler' that could not be resolved
/// <see cref="ErrorResultType{T}" />
/// </summary>
/// <param name="resultTask">The asynchronous <see cref="ResultType{T}" /></param>
Expand All @@ -100,7 +107,6 @@
/// The operation to perform for an
/// <see cref="ErrorResultType{T}" />
/// </param>
/// <param name="cancellationToken">The <see cref="CancellationToken" /></param>
/// <typeparam name="TIn">The input result value's type</typeparam>
/// <returns>The completed task</returns>
/// <exception cref="UnsupportedResultTypeException{TIn}">
Expand All @@ -110,30 +116,28 @@
/// </exception>
public static async Task MatchAsync<TIn>(
this Task<ResultType<TIn>> resultTask,
Func<TIn, CancellationToken, Task> okHandler,
Func<Error, CancellationToken, Task> errorHandler,
CancellationToken cancellationToken = default
Func<TIn, Task> okHandler,
Func<Error, Task> errorHandler
)
{
await resultTask.MatchAsync<TIn, Empty>(
async (value, token) =>
async value =>
{
await okHandler(value, token);
await okHandler(value);
return default;
},
async (error, token) =>
async error =>
{
await errorHandler(error, token);
await errorHandler(error);
return default;
},
cancellationToken
}
);
}

/// <summary>
/// Performs a match on the <see cref="ResultType{T}" />, invoking the
/// <see cref="okHandler" /> for an <see cref="OkResultType{T}" />

Check warning on line 139 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 139 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 139 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'okHandler' that could not be resolved
/// and the <see cref="errorHandler" /> for an

Check warning on line 140 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 140 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'errorHandler' that could not be resolved

Check warning on line 140 in src/FluentUtils.Monad/Extensions/MatchAsyncExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'errorHandler' that could not be resolved
/// <see cref="ErrorResultType{T}" />
/// </summary>
/// <param name="resultTask">The asynchronous <see cref="ResultType{T}" /></param>
Expand All @@ -145,7 +149,6 @@
/// The operation to perform for an
/// <see cref="ErrorResultType{T}" />
/// </param>
/// <param name="cancellationToken">The <see cref="CancellationToken" /></param>
/// <returns>The completed task</returns>
/// <exception cref="UnsupportedResultTypeException{TIn}">
/// The
Expand All @@ -154,12 +157,10 @@
/// </exception>
public static async Task MatchAsync(
this Task<ResultType<Empty>> resultTask,
Func<CancellationToken, Task> okHandler,
Func<Error, CancellationToken, Task> errorHandler,
CancellationToken cancellationToken = default
Func<Task> okHandler,
Func<Error, Task> errorHandler
) => await resultTask.MatchAsync(
(_, token) => okHandler(token),
errorHandler,
cancellationToken
_ => okHandler(),
errorHandler
);
}
6 changes: 6 additions & 0 deletions src/FluentUtils.Monad/Extensions/MatchExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
namespace FluentUtils.Monad.Extensions;

using System.Diagnostics;

/// <summary>
/// Extensions for matching on a <see cref="ResultType{T}" />
/// </summary>
Expand All @@ -8,7 +10,7 @@
{
/// <summary>
/// Performs a match on the <see cref="ResultType{T}" />, invoking the
/// <see cref="okHandler" /> for an <see cref="OkResultType{T}" />

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchExtensions.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchExtensions.cs

View workflow job for this annotation

GitHub Actions / Build solution and run tests

XML comment has cref attribute 'okHandler' that could not be resolved

Check warning on line 13 in src/FluentUtils.Monad/Extensions/MatchExtensions.cs

View workflow job for this annotation

GitHub Actions / Publish Monad NuGet Package

XML comment has cref attribute 'okHandler' that could not be resolved
/// and the <see cref="errorHandler" /> for an
/// <see cref="ErrorResultType{T}" />
/// </summary>
Expand All @@ -29,6 +31,7 @@
/// <see cref="ResultType{T}" /> is not one of <see cref="OkResultType{T}" />
/// or <see cref="ErrorResultType{T}" />
/// </exception>
[DebuggerStepperBoundary]
public static TOut Match<TIn, TOut>(
this ResultType<TIn> result,
Func<TIn, TOut> okHandler,
Expand Down Expand Up @@ -65,6 +68,7 @@
/// <see cref="ResultType{T}" /> is not one of <see cref="OkResultType{T}" />
/// or <see cref="ErrorResultType{T}" />
/// </exception>
[DebuggerStepperBoundary]
public static TOut Match<TOut>(
this ResultType<Empty> result,
Func<TOut> okHandler,
Expand Down Expand Up @@ -92,6 +96,7 @@
/// <see cref="ResultType{T}" /> is not one of <see cref="OkResultType{T}" />
/// or <see cref="ErrorResultType{T}" />
/// </exception>
[DebuggerStepperBoundary]
public static void Match<TIn>(
this ResultType<TIn> result,
Action<TIn> okHandler,
Expand Down Expand Up @@ -132,6 +137,7 @@
/// <see cref="ResultType{T}" /> is not one of <see cref="OkResultType{T}" />
/// or <see cref="ErrorResultType{T}" />
/// </exception>
[DebuggerStepperBoundary]
public static void Match(
this ResultType<Empty> result,
Action okHandler,
Expand Down
Loading
Loading