1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2024-10-17 09:42:45 +02:00
TweetDuck/lib/TweetLib.Utils/Data/Result.cs

65 lines
2.4 KiB
C#

using System;
namespace TweetLib.Utils.Data {
/// <summary>
/// Represents a result which either has a value of type <typeparamref name="T"/>, or an <see cref="Exception"/>.
/// </summary>
public sealed class Result<T> {
/// <summary>
/// Determines whether the <see cref="Result{T}"/> has a value.
/// </summary>
public bool HasValue => exception == null;
/// <summary>
/// Returns the value, or throws <see cref="InvalidOperationException"/> if no value is present.
/// </summary>
public T Value => HasValue ? value : throw new InvalidOperationException("Requested value from a failed result.");
/// <summary>
/// Returns the <see cref="Exception"/>, or throws <see cref="InvalidOperationException"/> if this <see cref="Result{T}"/> has a value.
/// </summary>
public Exception Exception => exception ?? throw new InvalidOperationException("Requested exception from a successful result.");
private readonly T value;
private readonly Exception? exception;
/// <summary>
/// Initializes a <see cref="Result{T}"/> with a value.
/// </summary>
public Result(T value) {
this.value = value;
this.exception = null;
}
/// <summary>
/// Initializes a <see cref="Result{T}"/> with an exception.
/// </summary>
public Result(Exception exception) {
this.value = default!;
this.exception = exception ?? throw new ArgumentNullException(nameof(exception));
}
/// <summary>
/// Executes one of the two provided <see cref="Action{T}"/> parameters depending on the state of the <see cref="Result{T}"/>.
/// </summary>
/// <param name="onSuccess">Executed if this <see cref="Result{T}"/> has a value.</param>
/// <param name="onException">Executed if this <see cref="Result{T}"/> has an exception.</param>
public void Handle(Action<T> onSuccess, Action<Exception> onException) {
if (HasValue) {
onSuccess(value);
}
else {
onException(exception!);
}
}
/// <summary>
/// If this <see cref="Result{T}"/> has a value, applies the <paramref name="mapper"/> function to it and returns a new <see cref="Result{T}"/> with the resulting value.
/// If this <see cref="Result{T}"/> has an exception, returns a <see cref="Result{T}"/> with the same exception but with type <typeparamref name="R"/>.
/// </summary>
public Result<R> Select<R>(Func<T, R> mapper) {
return HasValue ? new Result<R>(mapper(value)) : new Result<R>(exception!);
}
}
}