Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed bad overload. Bind should not take in a Func<Result> #220

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 122 additions & 56 deletions src/Ardalis.Result/ResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,25 @@ public static class ResultExtensions
/// <param name="func">A function to transform the source value to the destination type.</param>
/// <returns>A Result containing the transformed value or the appropriate error status.</returns>
/// <exception cref="NotSupportedException">Thrown when the Result status is not supported.</exception>
public static Result<TDestination> Map<TSource, TDestination>(this Result<TSource> result, Func<TSource, TDestination> func)
public static Result<TDestination> Map<TSource, TDestination>(
this Result<TSource> result,
Func<TSource, TDestination> func
)
{
return result.Status switch
{
ResultStatus.Ok => (Result<TDestination>)func(result),
ResultStatus.Created => string.IsNullOrEmpty(result.Location)
? Result<TDestination>.Created(func(result.Value))
: Result<TDestination>.Created(func(result.Value), result.Location),
? Result<TDestination>.Created(func(result.Value))
: Result<TDestination>.Created(func(result.Value), result.Location),
_ => HandleNonSuccessStatus<TSource, TDestination>(result),
};
}

public static Result<TDestination> Map<TDestination>(this Result result, Func<TDestination> func)
public static Result<TDestination> Map<TDestination>(
this Result result,
Func<TDestination> func
)
{
return result.Status switch
{
Expand All @@ -42,7 +48,8 @@ public static Result<TDestination> Map<TDestination>(this Result result, Func<TD

public static async Task<Result<TDestination>> MapAsync<TSource, TDestination>(
this Result<TSource> result,
Func<TSource, Task<TDestination>> func)
Func<TSource, Task<TDestination>> func
)
{
return result.Status switch
{
Expand All @@ -54,10 +61,10 @@ public static async Task<Result<TDestination>> MapAsync<TSource, TDestination>(
};
}


public static async Task<Result<TDestination>> MapAsync<TSource, TDestination>(
this Task<Result<TSource>> resultTask,
Func<TSource, Task<TDestination>> func)
Func<TSource, Task<TDestination>> func
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -72,7 +79,8 @@ public static async Task<Result<TDestination>> MapAsync<TSource, TDestination>(

public static async Task<Result<TDestination>> MapAsync<TDestination>(
this Result result,
Func<Task<TDestination>> func)
Func<Task<TDestination>> func
)
{
return result.Status switch
{
Expand All @@ -86,24 +94,26 @@ public static async Task<Result<TDestination>> MapAsync<TDestination>(

public static async Task<Result<TDestination>> MapAsync<TDestination>(
this Task<Result> resultTask,
Func<Task<TDestination>> func)
Func<Task<TDestination>> func
)
{
var result = await resultTask;
return await result.MapAsync(func);
}


public static async Task<Result<TDestination>> MapAsync<TSource, TDestination>(
this Task<Result<TSource>> resultTask,
Func<TSource, TDestination> func)
Func<TSource, TDestination> func
)
{
var result = await resultTask;
return result.Map(func);
}

public static async Task<Result<TDestination>> MapAsync<TDestination>(
this Task<Result> resultTask,
Func<TDestination> func)
Func<TDestination> func
)
{
var result = await resultTask;
return result.Map(func);
Expand All @@ -119,7 +129,10 @@ public static async Task<Result<TDestination>> MapAsync<TDestination>(
/// <param name="func">A function to transform the source value to the destination type.</param>
/// <returns>A Result containing the transformed value or the appropriate error status.</returns>
/// <exception cref="NotSupportedException">Thrown when the Result status is not supported.</exception>
public static Result<TDestination> Bind<TSource, TDestination>(this Result<TSource> result, Func<TSource, Result<TDestination>> bindFunc)
public static Result<TDestination> Bind<TSource, TDestination>(
this Result<TSource> result,
Func<TSource, Result<TDestination>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -129,7 +142,10 @@ public static Result<TDestination> Bind<TSource, TDestination>(this Result<TSour
};
}

public static Result<TDestination> Bind<TDestination>(this Result result, Func<Result, Result<TDestination>> bindFunc)
public static Result<TDestination> Bind<TDestination>(
this Result result,
Func<Result, Result<TDestination>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -139,7 +155,10 @@ public static Result<TDestination> Bind<TDestination>(this Result result, Func<R
};
}

public static Result Bind<TSource>(this Result<TSource> result, Func<Result<TSource>, Result> bindFunc)
public static Result Bind<TSource>(
this Result<TSource> result,
Func<TSource, Result> bindFunc
)
{
return result.Status switch
{
Expand All @@ -151,7 +170,8 @@ public static Result Bind<TSource>(this Result<TSource> result, Func<Result<TSou

public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(
this Task<Result<TSource>> resultTask,
Func<TSource, Task<Result<TDestination>>> bindFunc)
Func<TSource, Task<Result<TDestination>>> bindFunc
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -164,7 +184,8 @@ public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(

public static async Task<Result> BindAsync<TSource>(
this Task<Result<TSource>> resultTask,
Func<TSource, Task<Result>> bindFunc)
Func<TSource, Task<Result>> bindFunc
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -177,7 +198,8 @@ public static async Task<Result> BindAsync<TSource>(

public static async Task<Result> BindAsync<TSource>(
this Result<TSource> result,
Func<TSource, Task<Result>> bindFunc)
Func<TSource, Task<Result>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -189,7 +211,8 @@ public static async Task<Result> BindAsync<TSource>(

public static async Task<Result> BindAsync(
this Result result,
Func<Result, Task<Result>> bindFunc)
Func<Result, Task<Result>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -201,7 +224,8 @@ public static async Task<Result> BindAsync(

public static async Task<Result<TDestination>> BindAsync<TDestination>(
this Task<Result> resultTask,
Func<Result, Task<Result<TDestination>>> bindFunc)
Func<Result, Task<Result<TDestination>>> bindFunc
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -214,7 +238,8 @@ public static async Task<Result<TDestination>> BindAsync<TDestination>(

public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(
this Result<TSource> result,
Func<TSource, Task<Result<TDestination>>> bindFunc)
Func<TSource, Task<Result<TDestination>>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -226,7 +251,8 @@ public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(

public static async Task<Result> BindAsync<TSource, TDestination>(
this Result<TSource> result,
Func<TSource, Task<Result>> bindFunc)
Func<TSource, Task<Result>> bindFunc
)
{
return result.Status switch
{
Expand All @@ -236,7 +262,10 @@ public static async Task<Result> BindAsync<TSource, TDestination>(
};
}

public static async Task<Result> BindAsync(this Task<Result> resultTask, Func<Result, Task<Result>> bindFunc)
public static async Task<Result> BindAsync(
this Task<Result> resultTask,
Func<Result, Task<Result>> bindFunc
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -249,7 +278,8 @@ public static async Task<Result> BindAsync(this Task<Result> resultTask, Func<Re

public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(
this Task<Result<TSource>> resultTask,
Func<TSource, Result<TDestination>> bindFunc)
Func<TSource, Result<TDestination>> bindFunc
)
{
var result = await resultTask;
return result.Status switch
Expand All @@ -260,7 +290,9 @@ public static async Task<Result<TDestination>> BindAsync<TSource, TDestination>(
};
}

private static Result<TDestination> HandleNonSuccessStatus<TSource, TDestination>(Result<TSource> result)
private static Result<TDestination> HandleNonSuccessStatus<TSource, TDestination>(
Result<TSource> result
)
{
return result.Status switch
{
Expand All @@ -274,14 +306,22 @@ private static Result<TDestination> HandleNonSuccessStatus<TSource, TDestination
? Result<TDestination>.Forbidden(result.Errors.ToArray())
: Result<TDestination>.Forbidden(),
ResultStatus.Invalid => Result<TDestination>.Invalid(result.ValidationErrors),
ResultStatus.Error => Result<TDestination>.Error(new ErrorList(result.Errors.ToArray(), result.CorrelationId)),
ResultStatus.Error => Result<TDestination>.Error(
new ErrorList(result.Errors.ToArray(), result.CorrelationId)
),
ResultStatus.Conflict => result.Errors.Any()
? Result<TDestination>.Conflict(result.Errors.ToArray())
: Result<TDestination>.Conflict(),
ResultStatus.CriticalError => Result<TDestination>.CriticalError(result.Errors.ToArray()),
ResultStatus.Unavailable => Result<TDestination>.Unavailable(result.Errors.ToArray()),
ResultStatus.CriticalError => Result<TDestination>.CriticalError(
result.Errors.ToArray()
),
ResultStatus.Unavailable => Result<TDestination>.Unavailable(
result.Errors.ToArray()
),
ResultStatus.NoContent => Result<TDestination>.NoContent(),
_ => throw new NotSupportedException($"Result {result.Status} conversion is not supported."),
_ => throw new NotSupportedException(
$"Result {result.Status} conversion is not supported."
),
};
}

Expand All @@ -299,14 +339,22 @@ private static Result<TDestination> HandleNonSuccessStatus<TDestination>(Result
? Result<TDestination>.Forbidden(result.Errors.ToArray())
: Result<TDestination>.Forbidden(),
ResultStatus.Invalid => Result<TDestination>.Invalid(result.ValidationErrors),
ResultStatus.Error => Result<TDestination>.Error(new ErrorList(result.Errors.ToArray(), result.CorrelationId)),
ResultStatus.Error => Result<TDestination>.Error(
new ErrorList(result.Errors.ToArray(), result.CorrelationId)
),
ResultStatus.Conflict => result.Errors.Any()
? Result<TDestination>.Conflict(result.Errors.ToArray())
: Result<TDestination>.Conflict(),
ResultStatus.CriticalError => Result<TDestination>.CriticalError(result.Errors.ToArray()),
ResultStatus.Unavailable => Result<TDestination>.Unavailable(result.Errors.ToArray()),
ResultStatus.CriticalError => Result<TDestination>.CriticalError(
result.Errors.ToArray()
),
ResultStatus.Unavailable => Result<TDestination>.Unavailable(
result.Errors.ToArray()
),
ResultStatus.NoContent => Result<TDestination>.NoContent(),
_ => throw new NotSupportedException($"Result {result.Status} conversion is not supported."),
_ => throw new NotSupportedException(
$"Result {result.Status} conversion is not supported."
),
};
}

Expand All @@ -324,48 +372,66 @@ private static Result HandleNonSuccessStatus<TSource>(Result<TSource> result)
? Result.Forbidden(result.Errors.ToArray())
: Result.Forbidden(),
ResultStatus.Invalid => Result.Invalid(result.ValidationErrors),
ResultStatus.Error => Result.Error(new ErrorList(result.Errors.ToArray(), result.CorrelationId)),
ResultStatus.Error => Result.Error(
new ErrorList(result.Errors.ToArray(), result.CorrelationId)
),
ResultStatus.Conflict => result.Errors.Any()
? Result.Conflict(result.Errors.ToArray())
: Result.Conflict(),
ResultStatus.CriticalError => Result.CriticalError(result.Errors.ToArray()),
ResultStatus.Unavailable => Result.Unavailable(result.Errors.ToArray()),
ResultStatus.NoContent => Result.NoContent(),
_ => throw new NotSupportedException($"Result {result.Status} conversion is not supported."),
_ => throw new NotSupportedException(
$"Result {result.Status} conversion is not supported."
),
};
}

/// <summary>
/// Transforms a Result's type from a source type to a non-generic Result type.
/// </summary>
/// <typeparam name="TSource"></typeparam>
/// <param name="result"></param>
/// <returns></returns>
/// <exception cref="NotSupportedException"></exception>
/// <exception cref="NotSupportedException"></exception>
public static Result Map<TSource>(this Result<TSource> result)
{
switch (result.Status)
{
case ResultStatus.Ok: return Result.Success();
case ResultStatus.NotFound: return result.Errors.Any()
? Result.NotFound(result.Errors.ToArray())
: Result.NotFound();
case ResultStatus.Unauthorized: return result.Errors.Any()
? Result.Unauthorized(result.Errors.ToArray())
: Result.Unauthorized();
case ResultStatus.Forbidden: return result.Errors.Any()
? Result.Forbidden(result.Errors.ToArray())
: Result.Forbidden();
case ResultStatus.Invalid: return Result.Invalid(result.ValidationErrors);
case ResultStatus.Error: return Result.Error(new ErrorList(result.Errors.ToArray(), result.CorrelationId));
case ResultStatus.Conflict: return result.Errors.Any()
? Result.Conflict(result.Errors.ToArray())
: Result.Conflict();
case ResultStatus.CriticalError: return Result.CriticalError(result.Errors.ToArray());
case ResultStatus.Unavailable: return Result.Unavailable(result.Errors.ToArray());
case ResultStatus.NoContent: return Result.NoContent();
case ResultStatus.Ok:
return Result.Success();
case ResultStatus.NotFound:
return result.Errors.Any()
? Result.NotFound(result.Errors.ToArray())
: Result.NotFound();
case ResultStatus.Unauthorized:
return result.Errors.Any()
? Result.Unauthorized(result.Errors.ToArray())
: Result.Unauthorized();
case ResultStatus.Forbidden:
return result.Errors.Any()
? Result.Forbidden(result.Errors.ToArray())
: Result.Forbidden();
case ResultStatus.Invalid:
return Result.Invalid(result.ValidationErrors);
case ResultStatus.Error:
return Result.Error(
new ErrorList(result.Errors.ToArray(), result.CorrelationId)
);
case ResultStatus.Conflict:
return result.Errors.Any()
? Result.Conflict(result.Errors.ToArray())
: Result.Conflict();
case ResultStatus.CriticalError:
return Result.CriticalError(result.Errors.ToArray());
case ResultStatus.Unavailable:
return Result.Unavailable(result.Errors.ToArray());
case ResultStatus.NoContent:
return Result.NoContent();
default:
throw new NotSupportedException($"Result {result.Status} conversion is not supported.");
throw new NotSupportedException(
$"Result {result.Status} conversion is not supported."
);
}
}
}
Expand Down
Loading
Loading