Result<T>
Represents a result of operation which can be actual result or exception.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.ExceptionServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
namespace DotNext
{
[Serializable]
[StructLayout(LayoutKind.Auto)]
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public readonly struct Result<[System.Runtime.CompilerServices.Nullable(2)] T> : ISerializable
{
private const string ExceptionSerData = "Exception";
private const string ValueSerData = "Value";
private readonly T value;
[System.Runtime.CompilerServices.Nullable(2)]
private readonly ExceptionDispatchInfo exception;
public bool IsSuccessful => exception == null;
public T Value {
get {
exception?.Throw();
return value;
}
}
[System.Runtime.CompilerServices.Nullable(2)]
public Exception Error {
[System.Runtime.CompilerServices.NullableContext(2)]
get {
return exception?.SourceException;
}
}
public Result(T value)
{
this.value = value;
exception = null;
}
public Result(Exception error)
{
exception = ExceptionDispatchInfo.Capture(error);
value = default(T);
}
private Result(ExceptionDispatchInfo dispatchInfo)
{
value = default(T);
exception = dispatchInfo;
}
private Result(SerializationInfo info, StreamingContext context)
{
value = (T)info.GetValue("Value", typeof(T));
Exception ex = info.GetValue("Exception", typeof(Exception)) as Exception;
exception = ((ex != null) ? ExceptionDispatchInfo.Capture(ex) : null);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public static Result<T> FromOptional([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Optional<T> optional)
{
return optional.HasValue ? new Result<T>(optional.OrDefault()) : (optional.IsNull ? default(Result<T>) : new Result<T>(new InvalidOperationException(ExceptionMessages.OptionalNoValue)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private Result<TResult> Convert<[System.Runtime.CompilerServices.Nullable(2)] TResult, TConverter>(TConverter converter) where TConverter : struct, ISupplier<T, TResult>
{
if (this.exception == null)
try {
return ((ISupplier<T, TResult>)converter).Invoke(this.value);
} catch (Exception error) {
return new Result<TResult>(error);
}
return new Result<TResult>(this.exception);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Result<TResult> Convert<[System.Runtime.CompilerServices.Nullable(2)] TResult>(Converter<T, TResult> converter)
{
return Convert<TResult, DelegatingConverter<T, TResult>>(converter);
}
[System.Runtime.CompilerServices.NullableContext(2)]
[CLSCompliant(false)]
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Result<TResult> Convert<TResult>([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr converter)
{
return Convert<TResult, Supplier<T, TResult>>(converter);
}
public bool TryGet(out T value)
{
value = this.value;
return exception == null;
}
[System.Runtime.CompilerServices.NullableContext(2)]
public T Or(T defaultValue)
{
if (exception != null)
return defaultValue;
return value;
}
public T OrDefault()
{
return value;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
private T OrInvoke<TSupplier>(TSupplier defaultFunc) where TSupplier : struct, ISupplier<T>
{
if (this.exception != null)
return ((ISupplier<T>)defaultFunc).Invoke();
return this.value;
}
public T OrInvoke(Func<T> defaultFunc)
{
return OrInvoke((DelegatingSupplier<T>)defaultFunc);
}
[CLSCompliant(false)]
public T OrInvoke([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] IntPtr defaultFunc)
{
return OrInvoke((Supplier<T>)(long)defaultFunc);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[System.Runtime.CompilerServices.NullableContext(0)]
[return: System.Runtime.CompilerServices.Nullable(1)]
private T OrInvokeWithException<TSupplier>(TSupplier defaultFunc) where TSupplier : struct, ISupplier<Exception, T>
{
if (this.exception != null)
return ((ISupplier<Exception, T>)defaultFunc).Invoke(this.exception.SourceException);
return this.value;
}
public T OrInvoke(Func<Exception, T> defaultFunc)
{
return OrInvokeWithException((DelegatingSupplier<Exception, T>)defaultFunc);
}
[CLSCompliant(false)]
public T OrInvoke([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1,
1
})] IntPtr defaultFunc)
{
return OrInvokeWithException((Supplier<Exception, T>)(long)defaultFunc);
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
2
})]
public Result<object> Box()
{
if (exception != null)
return new Result<object>(exception);
return new Result<object>(value);
}
public static explicit operator T([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> result)
{
return result.Value;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Optional<T> TryGet()
{
if (exception != null)
return Optional<T>.None;
return new Optional<T>(value);
}
public static implicit operator Optional<T>([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> result)
{
return result.TryGet();
}
public static implicit operator Result<T>(T result)
{
return new Result<T>(result);
}
public static explicit operator Result<T>([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Optional<T> optional)
{
return FromOptional(ref optional);
}
public static bool operator &([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> left, [In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> right)
{
if (left.exception == null)
return right.exception == null;
return false;
}
public static bool operator true([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> result)
{
return result.exception == null;
}
public static bool operator false([In] [IsReadOnly] [System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] ref Result<T> result)
{
return result.exception != null;
}
void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
{
Exception ex = exception?.SourceException;
info.AddValue("Exception", ex, ex?.GetType() ?? typeof(Exception));
info.AddValue("Value", value, typeof(T));
}
public override string ToString()
{
object obj = exception?.SourceException.ToString();
if (obj == null) {
T val = value;
obj = (val?.ToString() ?? "<NULL>");
}
return (string)obj;
}
}
}