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; } } } }