src/Sirh3e.Rust/Result/Result.cs
namespace Sirh3e.Rust.Result;
public readonly partial struct Result<TOk, TErr> : ICloneable, IEnumerable<TOk>, IEquatable<Result<TOk, TErr>>
{
private readonly TOk _ok;
private readonly TErr _err;
private Result(TOk ok)
{
_ok = ok ?? throw new ArgumentNullException(nameof(ok));
IsOk = true;
_err = default;
}
private Result(TErr err)
{
_err = err ?? throw new ArgumentNullException(nameof(err));
IsOk = false;
_ok = default;
}
public static Result<TOk, TErr> Ok(TOk ok)
=> new(ok);
public static Result<TOk, TErr> Err(TErr err)
=> new(err);
public bool Equals(Result<TOk, TErr> other) => EqualityComparer<TOk>.Default.Equals(_ok, other._ok)
&& EqualityComparer<TErr>.Default.Equals(_err, other._err)
&& IsOk == other.IsOk;
public IEnumerator<TOk> GetEnumerator()
#if NETCOREAPP1_0_OR_GREATER || NET46_OR_GREATER || NETSTANDARD1_3_OR_GREATER
=> new ResultEnumerator<TOk>(IsOk ? new[] { _ok } : Array.Empty<TOk>());
#else
=> new ResultEnumerator<TOk>(IsOk ? new[] { _ok } : new TOk[0]);
#endif
public override bool Equals(object obj)
=> obj is Result<TOk, TErr> other && Equals(other);
public override int GetHashCode()
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
return HashCode.Combine(_ok, _err, IsOk);
#else
//Thx to https://rehansaeed.com/gethashcode-made-easy/
var hashCode = 17;
hashCode = hashCode * 23 + (_ok == null ? 0 : _ok.GetHashCode());
hashCode = hashCode * 23 + (_err == null ? 0 : _err.GetHashCode());
hashCode = hashCode * 23 + IsErr.GetHashCode();
return hashCode;
#endif
}
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
public Result<TOk, TErr> Clone()
=> IsOk ? Ok(_ok) : Err(_err);
object ICloneable.Clone()
=> Clone();
public static implicit operator Result<TOk, TErr>(Err<TErr> err)
=> Err(err.Value);
public static implicit operator Result<TOk, TErr>(Ok<TOk> ok)
=> Ok(ok.Value);
public static bool operator ==(Result<TOk, TErr> left, Result<TOk, TErr> right)
=> left.Equals(right);
public static bool operator !=(Result<TOk, TErr> left, Result<TOk, TErr> right)
=> !(left == right);
}