namespace System { enum Result { case Ok(T _val); case Err(void _err); T Unwrap() { switch (this) { case .Ok(var val): return val; case .Err: { Internal.FatalError("Unhandled error in result", 2); } } } 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] public static void NoDispose() { } public static void NoDispose() where TVal : IDisposable { Internal.FatalError("Result must be disposed", 1); } public void ReturnValueDiscarded() { if (this case .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(); } } /*extension Result where T : class { public static T operator?(Self val) { switch (val) { case .Ok(let inner): return inner; case .Err: return default; } } }*/ enum Result { case Ok(T val); case Err(TErr err); T Unwrap() { switch (this) { case .Ok(var val): return val; case .Err(var err): { String errStr = scope String(); err.ToString(errStr); String showErr = scope String(); showErr.ConcatInto("Unhandled error in result:\n ", errStr); Internal.FatalError(showErr, 2); } } } 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] public static void NoDispose() { } public static void NoDispose() where TVal : IDisposable { Internal.FatalError("Result must be disposed", 1); } public void ReturnValueDiscarded() { if (this case .Err(var err)) { String errStr = scope String(); err.ToString(errStr); String showErr = scope String(); showErr.ConcatInto("Unhandled error in result:\n ", errStr); Internal.FatalError(showErr, 1); } 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(); } } }