2019-08-23 11:56:54 -07:00
|
|
|
namespace System
|
|
|
|
{
|
2020-04-11 10:20:56 -07:00
|
|
|
enum Result<T> : IDisposable
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
2021-07-21 07:43:11 -07:00
|
|
|
[Inline]
|
2019-08-23 11:56:54 -07:00
|
|
|
get
|
|
|
|
{
|
|
|
|
return Unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-21 07:43:11 -07:00
|
|
|
[Inline]
|
2019-08-23 11:56:54 -07:00
|
|
|
public static implicit operator Result<T>(T value)
|
|
|
|
{
|
|
|
|
return .Ok(value);
|
|
|
|
}
|
|
|
|
|
2021-07-21 07:43:11 -07:00
|
|
|
[Inline]
|
2019-08-23 11:56:54 -07:00
|
|
|
public static implicit operator T(Result<T> result)
|
|
|
|
{
|
|
|
|
return result.Unwrap();
|
|
|
|
}
|
|
|
|
|
2021-07-21 07:43:11 -07:00
|
|
|
[Inline]
|
2019-08-23 11:56:54 -07:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-04-27 15:09:10 -07:00
|
|
|
public static nullable(T) operator?(Self val)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
|
|
|
case .Ok(let inner): return inner;
|
|
|
|
case .Err: return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-12 09:44:39 -07:00
|
|
|
[SkipCall]
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
[SkipCall]
|
|
|
|
static void NoDispose<TVal>()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void NoDispose<TVal>() where TVal : IDisposable
|
|
|
|
{
|
|
|
|
Internal.FatalError("Result must be disposed", 1);
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
public void ReturnValueDiscarded()
|
|
|
|
{
|
|
|
|
if (this case .Err(let err))
|
|
|
|
Internal.FatalError("Unhandled error in result", 1);
|
2019-09-12 09:44:39 -07:00
|
|
|
NoDispose<T>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Result<T> where T : IDisposable
|
|
|
|
{
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
if (this case .Ok(var val))
|
|
|
|
val.Dispose();
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-11 10:20:56 -07:00
|
|
|
enum Result<T, TErr> : IDisposable
|
2019-08-23 11:56:54 -07:00
|
|
|
{
|
|
|
|
case Ok(T val);
|
|
|
|
case Err(TErr err);
|
|
|
|
|
|
|
|
T Unwrap()
|
|
|
|
{
|
|
|
|
switch (this)
|
|
|
|
{
|
|
|
|
case .Ok(var val): return val;
|
|
|
|
case .Err(var err):
|
|
|
|
{
|
2020-05-13 07:39:56 -07:00
|
|
|
Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n {}", err), 2);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-21 05:48:44 -08:00
|
|
|
public T Value
|
|
|
|
{
|
|
|
|
get
|
|
|
|
{
|
|
|
|
return Unwrap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
public static implicit operator Result<T, TErr>(T value)
|
|
|
|
{
|
|
|
|
return .Ok(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static implicit operator T(Result<T, TErr> 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);
|
|
|
|
}
|
|
|
|
|
2020-04-27 15:09:10 -07:00
|
|
|
public static nullable(T) operator?(Self val)
|
|
|
|
{
|
|
|
|
switch (val)
|
|
|
|
{
|
|
|
|
case .Ok(let inner): return inner;
|
|
|
|
case .Err: return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-12 09:44:39 -07:00
|
|
|
[SkipCall]
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
[SkipCall]
|
|
|
|
static void NoDispose<TVal>()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void NoDispose<TVal>() where TVal : IDisposable
|
|
|
|
{
|
|
|
|
Internal.FatalError("Result must be disposed", 1);
|
|
|
|
}
|
|
|
|
|
2019-08-23 11:56:54 -07:00
|
|
|
public void ReturnValueDiscarded()
|
|
|
|
{
|
|
|
|
if (this case .Err(var err))
|
|
|
|
{
|
2020-05-13 07:39:56 -07:00
|
|
|
Internal.FatalError(scope String()..AppendF("Unhandled error in result:\n {}", err), 1);
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
2019-09-12 09:44:39 -07:00
|
|
|
NoDispose<T>();
|
|
|
|
NoDispose<TErr>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Result<T, TErr> where T : IDisposable
|
|
|
|
{
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
if (this case .Ok(var val))
|
|
|
|
val.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Result<T, TErr> where TErr : IDisposable
|
|
|
|
{
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
if (this case .Err(var err))
|
|
|
|
err.Dispose();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extension Result<T, TErr> 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();
|
2019-08-23 11:56:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|