namespace System { enum Result : IDisposable { case Ok(T val); case Err(void err); [Inline] T Unwrap() { switch (this) { case .Ok(var val): return val; case .Err: { Internal.FatalError("Unhandled error in result", 2); } } } public T Value { get { return Unwrap(); } } public static implicit operator Result(T value) { return .Ok(value); } public static implicit operator T(Result result) { return result.Unwrap(); } public void IgnoreError() { } public T Get() { return Unwrap(); } public T Get(T defaultVal) { if (this case .Ok(var val)) return val; return defaultVal; } public T GetValueOrDefault() { if (this case .Ok(var val)) return val; return default(T); } public static nullable(T) operator?(Self val) { switch (val) { case .Ok(let inner): return inner; case .Err: return null; } } [SkipCall] public void Dispose() { } [SkipCall] static void NoDispose() { } static void NoDispose() where TVal : IDisposable { Internal.FatalError("Result must be disposed", 1); } public void ReturnValueDiscarded() { if (this case .Err(let err)) Internal.FatalError("Unhandled error in result", 1); NoDispose(); } } extension Result where T : IDisposable { public void Dispose() { if (this case .Ok(var val)) val.Dispose(); } } enum Result : IDisposable { case Ok(T val); case Err(TErr err); T Unwrap() { switch (this) { case .Ok(var val): return val; case .Err(var err): { Internal.FatalError("Unhandled error in result"); } } } public T Value { get { return Unwrap(); } } public static implicit operator Result(T value) { return .Ok(value); } public static implicit operator T(Result result) { return result.Unwrap(); } public void IgnoreError() { } public T Get() { return Unwrap(); } public T Get(T defaultVal) { if (this case .Ok(var val)) return val; return defaultVal; } public T GetValueOrDefault() { if (this case .Ok(var val)) return val; return default(T); } public static nullable(T) operator?(Self val) { switch (val) { case .Ok(let inner): return inner; case .Err: return null; } } [SkipCall] public void Dispose() { } [SkipCall] static void NoDispose() { } static void NoDispose() where TVal : IDisposable { Internal.FatalError("Result must be disposed", 1); } public void ReturnValueDiscarded() { if (this case .Err(var err)) { Internal.FatalError("Unhandled error in result"); } NoDispose(); NoDispose(); } } extension Result where T : IDisposable { public void Dispose() { if (this case .Ok(var val)) val.Dispose(); } } extension Result where TErr : IDisposable { public void Dispose() { if (this case .Err(var err)) err.Dispose(); } } extension Result where T : IDisposable where TErr : IDisposable { public void Dispose() { if (this case .Ok(var val)) val.Dispose(); else if (this case .Err(var err)) err.Dispose(); } } }