using System;
namespace Umbraco.Core
{
///
/// Provides ways to create attempts.
///
public static class Attempt
{
///
/// Creates a successful attempt with a result.
///
/// The type of the attempted operation result.
/// The result of the attempt.
/// The successful attempt.
public static Attempt Succeed(T result)
{
return Attempt.Succeed(result);
}
///
/// Creates a failed attempt with a result.
///
/// The type of the attempted operation result.
/// The result of the attempt.
/// The failed attempt.
public static Attempt Fail(T result)
{
return Attempt.Fail(result);
}
///
/// Creates a failed attempt with a result and an exception.
///
/// The type of the attempted operation result.
/// The result of the attempt.
/// The exception causing the failure of the attempt.
/// The failed attempt.
public static Attempt Fail(T result, Exception exception)
{
return Attempt.Fail(result, exception);
}
///
/// Creates a successful or a failed attempt, with a result.
///
/// The type of the attempted operation result.
/// A value indicating whether the attempt is successful.
/// The result of the attempt.
/// The attempt.
public static Attempt If(bool success, T result)
{
return Attempt.SucceedIf(success, result);
}
///
/// Executes an attempt function, with callbacks.
///
/// The type of the attempted operation result.
/// The attempt returned by the attempt function.
/// An action to execute in case the attempt succeeds.
/// An action to execute in case the attempt fails.
/// The outcome of the attempt.
/// Runs or depending on the
/// whether the attempt function reports a success or a failure.
public static Outcome Try(Attempt attempt, Action onSuccess, Action onFail = null)
{
if (attempt.Success)
{
onSuccess(attempt.Result);
return Outcome.Success;
}
if (onFail != null)
{
onFail(attempt.Exception);
}
return Outcome.Failure;
}
///
/// Represents the outcome of an attempt.
///
/// Can be a success or a failure, and allows for attempts chaining.
public struct Outcome
{
private readonly bool _success;
///
/// Gets an outcome representing a success.
///
public static readonly Outcome Success = new Outcome(true);
///
/// Gets an outcome representing a failure.
///
public static readonly Outcome Failure = new Outcome(false);
private Outcome(bool success)
{
_success = success;
}
///
/// Executes another attempt function, if the previous one failed, with callbacks.
///
/// The type of the attempted operation result.
/// The attempt function to execute, returning an attempt.
/// An action to execute in case the attempt succeeds.
/// An action to execute in case the attempt fails.
/// If it executes, returns the outcome of the attempt, else returns a success outcome.
///
/// Executes only if the previous attempt failed, else does not execute and return a success outcome.
/// If it executes, then runs or depending on the
/// whether the attempt function reports a success or a failure.
///
public Outcome OnFailure(Func> nextFunction, Action onSuccess, Action onFail = null)
{
return _success
? Success
: ExecuteNextFunction(nextFunction, onSuccess, onFail);
}
///
/// Executes another attempt function, if the previous one succeeded, with callbacks.
///
/// The type of the attempted operation result.
/// The attempt function to execute, returning an attempt.
/// An action to execute in case the attempt succeeds.
/// An action to execute in case the attempt fails.
/// If it executes, returns the outcome of the attempt, else returns a failed outcome.
///
/// Executes only if the previous attempt succeeded, else does not execute and return a success outcome.
/// If it executes, then runs or depending on the
/// whether the attempt function reports a success or a failure.
///
public Outcome OnSuccess(Func> nextFunction, Action onSuccess, Action onFail = null)
{
return _success
? ExecuteNextFunction(nextFunction, onSuccess, onFail)
: Failure;
}
private static Outcome ExecuteNextFunction(Func> nextFunction, Action onSuccess, Action onFail = null)
{
var attempt = nextFunction();
if (attempt.Success)
{
onSuccess(attempt.Result);
return Success;
}
if (onFail != null)
{
onFail(attempt.Exception);
}
return Failure;
}
}
}
}