Last active
July 3, 2024 09:42
-
-
Save BoeseB/6c465bc8faaac5541449 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static class AsyncResultExtensions | |
{ | |
//added to chain awaitable methods | |
public static async Task<Result<TResult>> OnSuccessAsync<T, TResult>(this Result<T> result, Func<T, Task<Result<TResult>>> func) | |
{ | |
var res = result; | |
if (res.Failed) | |
return Result<TResult>.Fail(res.Error); | |
return await func(res.Value); | |
} | |
} | |
//Usage example | |
private async void DoSomething(string url) | |
{ | |
(await OpcUrl.Create(url) | |
.OnSuccessAsync(address => InternalSearchEndpoints(address))) | |
.OnSuccess(list => UpdateEndpointList(list)) | |
.OnFailure( error => _eventStream.Push(new DiscoveryError(error))); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct Result | |
{ | |
private static readonly Result _ok = new Result(true, String.Empty); | |
private static readonly Result<Unit> _okUnit = Result<Unit>.Ok(Unit.Default); | |
public bool Succeeded { get; } | |
public string Error { get; } | |
public bool Failed | |
{ | |
get { return !Succeeded; } | |
} | |
private Result( bool success, string error) | |
{ | |
Contracts.Require(success || !string.IsNullOrEmpty(error)); | |
Contracts.Require(!success || string.IsNullOrEmpty(error)); | |
Succeeded = success; | |
Error = error; | |
} | |
public static implicit operator Result<Unit>(Result result) | |
{ | |
if (result.Failed) | |
{ | |
return Result<Unit>.Fail(result.Error); | |
} | |
return _okUnit; | |
} | |
public static Result Ok() | |
{ | |
return _ok; | |
} | |
public static Result Fail(string message) | |
{ | |
return new Result(false, message); | |
} | |
//Added for type inference so we can call Result.Ok(myvalue) without any type arguments | |
public static Result<T> Ok<T>(T value) | |
{ | |
return Result<T>.Ok(value); | |
} | |
} | |
public struct Result<T> | |
{ | |
public T Value { get; } | |
private Result([AllowNull] T value, bool success, string error) | |
{ | |
Contracts.Require(success || !string.IsNullOrEmpty(error)); | |
Contracts.Require(!success || string.IsNullOrEmpty(error)); | |
Contracts.Require(value != null || !success); | |
Succeeded = success; | |
Error = error; | |
Value = value; | |
} | |
public bool Succeeded { get; } | |
public string Error { get; } | |
public bool Failed | |
{ | |
get { return !Succeeded; } | |
} | |
public static Result<T> Fail(string message) | |
{ | |
return new Result<T>(default(T), false, message); | |
} | |
public static Result<T> Ok(T value) | |
{ | |
return new Result<T>(value, true, String.Empty); | |
} | |
public static Result Combine(params Result[] results) | |
{ | |
foreach (Result result in results) | |
{ | |
if (result.Failed) | |
return result; | |
} | |
return Result.Ok(); | |
} | |
//To make Combine work with Result<T> | |
public static implicit operator Result(Result<T> result) | |
{ | |
if (result.Failed) | |
{ | |
return Result.Fail(result.Error); | |
} | |
return Result.Ok(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class ResultExtensions | |
{ | |
public static Result OnSuccess(this Result result, Func<Result> func) | |
{ | |
if (result.Failed) | |
return result; | |
return func(); | |
} | |
public static Result OnSuccess<T>(this Result<T> result, Func<T, Result> func) | |
{ | |
if(result.Failed) { | |
return Result.Fail(result.Error); | |
} | |
return func(result.Value); | |
} | |
public static Result OnSuccess(this Result result, Action action) | |
{ | |
if (result.Failed) | |
return result; | |
action(); | |
return Result.Ok(); | |
} | |
public static Result OnSuccess<T>(this Result<T> result, Action<T> action) | |
{ | |
if (result.Failed) | |
return Result.Fail(result.Error); | |
action(result.Value); | |
return Result.Ok(); | |
} | |
public static Result<T> OnSuccess<T>(this Result result, Func<T> func) | |
{ | |
if (result.Failed) | |
return Result<T>.Fail(result.Error); | |
return Result<T>.Ok(func()); | |
} | |
public static Result<T> OnSuccess<T>(this Result result, Func<Result<T>> func) | |
{ | |
if (result.Failed) | |
return Result<T>.Fail(result.Error); | |
return func(); | |
} | |
public static Result<TResult> OnSuccess<T, TResult>(this Result<T> result, Func<T, Result<TResult>> func) | |
{ | |
if (result.Failed) | |
return Result<TResult>.Fail(result.Error); | |
return func(result.Value); | |
} | |
public static Result OnFailure(this Result result, Action<string> action) | |
{ | |
if (result.Failed) | |
{ | |
action(result.Error); | |
} | |
return result; | |
} | |
public static Result OnBoth(this Result result, Action<Result> action) | |
{ | |
action(result); | |
return result; | |
} | |
public static T OnBoth<T>(this Result result, Func<Result, T> func) | |
{ | |
return func(result); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct Unit : IEquatable<Unit> | |
{ | |
public static readonly Unit Default = new Unit(); | |
public override int GetHashCode() => | |
0; | |
public override bool Equals(object obj) => | |
obj is Unit; | |
public override string ToString() => | |
"()"; | |
public bool Equals(Unit other) => | |
true; | |
public static bool operator ==(Unit lhs, Unit rhs) => | |
true; | |
public static bool operator !=(Unit lhs, Unit rhs) => | |
false; | |
/// <summary> | |
/// Provide an alternative value to unit | |
/// </summary> | |
/// <typeparam name="T">Alternative value type</typeparam> | |
/// <param name="anything">Alternative value</param> | |
/// <returns>Alternative value</returns> | |
public T Return<T>(T anything) => anything; | |
/// <summary> | |
/// Provide an alternative value to unit | |
/// </summary> | |
/// <typeparam name="T">Alternative value type</typeparam> | |
/// <param name="anything">Alternative value</param> | |
/// <returns>Alternative value</returns> | |
public T Return<T>(Func<T> anything) => anything(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment