using System; using System.Diagnostics; namespace Discord { //Based on https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/Nullable.cs [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public struct Optional { public static Optional Unspecified => default(Optional); private readonly T _value; /// Gets the value for this parameter. /// This property has no value set. public T Value { get { if (!IsSpecified) throw new InvalidOperationException("This property has no value set."); return _value; } } /// Returns true if this value has been specified. public bool IsSpecified { get; } /// Creates a new Parameter with the provided value. public Optional(T value) { _value = value; IsSpecified = true; } public T GetValueOrDefault() => _value; public T GetValueOrDefault(T defaultValue) => IsSpecified ? _value : defaultValue; public override bool Equals(object other) { if (!IsSpecified) return other == null; if (other == null) return false; return _value.Equals(other); } public override int GetHashCode() => IsSpecified ? _value.GetHashCode() : 0; public override string ToString() => IsSpecified ? _value?.ToString() : null; private string DebuggerDisplay => IsSpecified ? (_value?.ToString() ?? "") : ""; public static implicit operator Optional(T value) => new Optional(value); public static explicit operator T(Optional value) => value.Value; } public static class Optional { public static Optional Create() => Optional.Unspecified; public static Optional Create(T value) => new Optional(value); public static T? ToNullable(this Optional val) where T : struct => val.IsSpecified ? val.Value : (T?)null; } }