Skip to content

Commit

Permalink
result
Browse files Browse the repository at this point in the history
  • Loading branch information
vip32 committed Nov 13, 2024
1 parent b1030b6 commit f7622e5
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 2 deletions.
3 changes: 1 addition & 2 deletions docs/features-results.md
Original file line number Diff line number Diff line change
Expand Up @@ -1011,8 +1011,7 @@ public async Task<Result<Order>> ProcessOrderAsync(Order order)
.FindOneResultAsync(order.ProductId);

if (inventoryResult.IsFailure)
return Result<Order>.Failure()
.WithErrors(inventoryResult.Errors);
return inventoryResult.For<Order>(); // convert to Order result
// Insert order
var orderResult = await _orderRepository
Expand Down
26 changes: 26 additions & 0 deletions src/Common.Results/Result{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,32 @@ public static implicit operator Result<T>(Result result) =>
() => Success().WithMessages(result.Messages).WithErrors(result.Errors),
_ => Failure().WithMessages(result.Messages).WithErrors(result.Errors));

// /// <summary>
// /// Implicitly converts a Result{T} to a Result{TOutput}.
// /// </summary>
// /// <typeparam name="TOutput">The target type of the conversion.</typeparam>
// /// <param name="result">The Result{T} to convert.</param>
// /// <returns>A new Result{TOutput} with the same success state, messages, and errors.</returns>
// /// <example>
// /// <code>
// /// var intResult = Result{int}.Failure()
// /// .WithMessage("Processing failed")
// /// .WithError(new ValidationError("Invalid value"));
// ///
// /// Result{string} strResult = intResult; // Implicit conversion
// /// </code>
// /// </example>
// public static implicit operator Result<TOutput>(Result<T> result)
// {
// return result.Match(
// _ => Result<TOutput>.Success()
// .WithMessages(result.Messages)
// .WithErrors(result.Errors),
// _ => Result<TOutput>.Failure()
// .WithMessages(result.Messages)
// .WithErrors(result.Errors));
// }

/// <summary>
/// Creates a successful Result{T} with a specified value.
/// </summary>
Expand Down
115 changes: 115 additions & 0 deletions tests/Common.UnitTests/Results/Result{T}Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,19 @@ public void Failure_WithVariousOverloads_CreatesFailureResults()
Should.Throw<InvalidOperationException>(() => result7.Value);
}

public Result<string> For_ConversionBetweenTypes1()
{
// Arrange
var value = this.faker.Random.Int(1, 100);
var message = this.faker.Lorem.Sentence();
var error = new Error("Test error");

var successResult = Result<int>.Success(value).WithMessage(message);
var failureResult = Result<int>.Failure().WithMessage(message).WithError(error);

return failureResult.For<string>(); //explicit conversion
}

[Fact]
public void For_ConversionBetweenTypes_MaintainsStateAndMessages()
{
Expand Down Expand Up @@ -916,4 +929,106 @@ public interface IDatabase

Task<bool> PersonExistsAsync(EmailAddressStub email, CancellationToken ct);
}

[Fact]
public void ImplicitConversion_ValueToResult_WorksCorrectly()
{
// Arrange
var value = this.faker.Random.Int(1, 100);

// Act
Result<int> result = value;

// Assert
result.ShouldBeSuccess();
result.ShouldBeValue(value);
}

[Fact]
public void ImplicitConversion_TaskToResult_WorksCorrectly()
{
// Arrange
var value = this.faker.Random.Int(1, 100);
var task = Task.FromResult(value);

// Act
Result<int> result = task;

// Assert
result.ShouldBeSuccess();
result.ShouldBeValue(value);
}

[Fact]
public void ImplicitConversion_ResultToBool_WorksCorrectly()
{
// Arrange
var successResult = Result<int>.Success(42);
var failureResult = Result<int>.Failure();

// Act
bool successBool = successResult;
bool failureBool = failureResult;

// Assert
successBool.ShouldBeTrue();
failureBool.ShouldBeFalse();
}

[Fact]
public void ImplicitConversion_ResultToNonGenericResult_WorksCorrectly()
{
// Arrange
var successResult = Result<int>.Success(42);
var failureResult = Result<int>.Failure();

// Act
Result nonGenericSuccess = successResult;
Result nonGenericFailure = failureResult;

// Assert
nonGenericSuccess.ShouldBeSuccess();
nonGenericFailure.ShouldBeFailure();
}

[Fact]
public void ImplicitConversion_NonGenericResultToResult_WorksCorrectly()
{
// Arrange
var nonGenericSuccess = Result.Success().WithMessage("Success");
var nonGenericFailure = Result.Failure().WithMessage("Failure");

// Act
Result<int> successResult = nonGenericSuccess;
Result<int> failureResult = nonGenericFailure;

// Assert
successResult.ShouldBeSuccess();
successResult.ShouldContainMessage("Success");

failureResult.ShouldBeFailure();
failureResult.ShouldContainMessage("Failure");
}

[Fact]
public void ForConversion_ResultToResultOfDifferentType_WorksCorrectly()
{
// Arrange
var successResult = Result<int>.Success(42).WithMessage("Success");
var failureResult = Result<int>.Failure().WithMessage("Failure").WithError(new Error("Test error"));

// Act
// ReSharper disable once SuggestVarOrType_Elsewhere
Result<string> convertedSuccessResult = successResult.For<string>();
// ReSharper disable once SuggestVarOrType_Elsewhere
Result<string> convertedFailureResult = failureResult.For<string>();

// Assert
convertedSuccessResult.ShouldBeSuccess();
convertedSuccessResult.ShouldContainMessage("Success");

convertedFailureResult.ShouldBeFailure();
convertedFailureResult.ShouldContainMessage("Failure");
convertedFailureResult.ShouldContainError<Error>();
}
}

0 comments on commit f7622e5

Please sign in to comment.