using System; namespace Wabbajack { public struct GetResponse : IEquatable>, IErrorResponse { public static readonly GetResponse Failure = new GetResponse(); public readonly T Value; public readonly bool Succeeded; public readonly Exception Exception; private readonly string _reason; public bool Failed => !Succeeded; public string Reason { get { if (this.Exception != null) { return this.Exception.ToString(); } return _reason; } } bool IErrorResponse.Succeeded => this.Succeeded; Exception IErrorResponse.Exception => this.Exception; private GetResponse( bool succeeded, T val = default(T), string reason = null, Exception ex = null) { this.Value = val; this.Succeeded = succeeded; this._reason = reason; this.Exception = ex; } public bool Equals(GetResponse other) { return this.Succeeded == other.Succeeded && object.Equals(this.Value, other.Value); } public override bool Equals(object obj) { if (!(obj is GetResponse rhs)) return false; return Equals(rhs); } public override int GetHashCode() { return HashHelper.GetHashCode(Value) .CombineHashCode(Succeeded.GetHashCode()); } public override string ToString() { return $"({(Succeeded ? "Success" : "Fail")}, {Value}, {Reason})"; } public GetResponse BubbleFailure() { return new GetResponse( succeeded: false, reason: this._reason, ex: this.Exception); } public GetResponse Bubble(Func conv) { return new GetResponse( succeeded: this.Succeeded, val: conv(this.Value), reason: this._reason, ex: this.Exception); } public T EvaluateOrThrow() { if (this.Succeeded) { return this.Value; } throw new ArgumentException(this.Reason); } #region Factories public static GetResponse Succeed(T value) { return new GetResponse(true, value); } public static GetResponse Succeed(T value, string reason) { return new GetResponse(true, value, reason); } public static GetResponse Fail(string reason) { return new GetResponse(false, reason: reason); } public static GetResponse Fail(T val, string reason) { return new GetResponse(false, val, reason); } public static GetResponse Fail(Exception ex) { return new GetResponse(false, ex: ex); } public static GetResponse Fail(T val, Exception ex) { return new GetResponse(false, val, ex: ex); } public static GetResponse Fail(T val) { return new GetResponse(false, val); } public static GetResponse Create(bool successful, T val = default(T), string reason = null) { return new GetResponse(successful, val, reason); } #endregion } }