Skip to content

SaahilClaypool/SharpResult

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sharp Result

Inspired by:

Features:

  • Easily box and unbox error values.
    • Success results are implicitly converted to success results
    • Error types can be created without specifying generics.
    • Match can be used to convert both success and errors to the same unwrapped type
    • Unwrap can be used to unsafely get the successful values
  • Easily chain together results (Railway oriented programming with Bind)

Examples

Example unboxing results

using static SharpResult.Result;

public class ResultTests
{
    [Fact]
    public void BasicErrorConstruction()
    {
        Result<int, string> result = Error("error");
        Assert.True(result.IsError);
        Assert.Equal("error", result.Error);
        Assert.Equal("error", result.Match(ok => ok.ToString(), err => err));
    }

    [Fact]
    public void BasicOkConstruction()
    {
        Result<int, string> result = 100;
        Assert.False(result.IsError);
        Assert.True(result.IsOk);
        Assert.Equal(100, result.Ok);
        Assert.Equal(100, result.Match(ok => ok, err => throw new System.Exception("unreachable")));
    }
}

Example bind usage

public string HandleRequest(string request) =>
    validate(request)
        .Bind(canonicalizeEmail)
        .Bind(trySaveRequest)
        .Bind(_ => "ok")
        .Match(ok => ok, err => err);

private static Result<string, string> validate(string request) { }
private static Result<string, string> trySaveRequest(string arg) { }
// bind can take either functions taking / returning results, OR functions taking the success / error values
private static string canonicalizeEmail(string request) { } 

Without bind

// without bind
public string HandleRequestWithoutBind(string request)
{
    var isValid = validateRequest(request);
    if (!isValid)
    {
        return "Error: validation";
    }

    canonicalizeEmail(request);

    try 
    {
        saveRequest(request);
    }
    catch
    {
        return "Error: save";
    }

    return "ok";
}

Create result types from functions throwing exceptions

[Fact]
public void Try_FunctionsReturningValuesAreConvertedToOk()
{
    string okFunc() => "ok";

    var tryOk = Result.Try(okFunc);
    Assert.True(tryOk.IsOk);
    Assert.Equal(okFunc(), tryOk.Unwrap());
}

[Fact]
public void Try_FunctionsThrowingExceptionsAreConvertedToErrors()
{
    string errorFunc() => throw new System.Exception("error");

    var tryError = Result.Try(errorFunc);
    Assert.False(tryError.IsOk);
    Assert.Equal("error", tryError.Error.Message);
}

About

Low ceremony result and option types for C#

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages