Skip to content

Instantly share code, notes, and snippets.

@fakhrulhilal
Last active July 5, 2023 00:48
Show Gist options
  • Save fakhrulhilal/c016857dfd78ac210a16a347dc60cdb8 to your computer and use it in GitHub Desktop.
Save fakhrulhilal/c016857dfd78ac210a16a347dc60cdb8 to your computer and use it in GitHub Desktop.
C# monad class for handling outcome
public abstract record Result
{
#region Helper methods
public static Success Ok() => new();
public static Success.WithValue<T> Ok<T>(T value) => new(value);
public static Failure Fail(string reason) => new(Codes.Unprocessable, reason);
public static Failure Error(Exception exception) => new(Codes.Unknown, exception.Message);
public static Failure NotFound(string entity) => new(Codes.NotFound, $"{entity} is not found.");
public static Failure.Invalid Reject(IDictionary<string, string[]> errors) => new(errors);
#endregion
#region Type definitions
public abstract record SuccessBase : Result;
public sealed record Success : SuccessBase
{
public sealed record WithValue<T>(T Value) : SuccessBase;
}
public abstract record FailureBase(int Code, string Reason) : Result;
public sealed record Failure(int Code, string Reason) : FailureBase(Code, Reason)
{
public sealed record Unknown(Exception Exception) : FailureBase(Codes.Unknown, Exception.Message);
public sealed record Invalid(IDictionary<string, string[]> Errors) : FailureBase(
Codes.BadRequest, "One or more validation failures have occured.");
}
#endregion
}
file struct Codes
{
public const int BadRequest = 400;
public const int NotFound = 404;
public const int Unprocessable = 422;
public const int Unknown = 500;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment