Giter Site home page Giter Site logo

goodeuser / ergo.result Goto Github PK

View Code? Open in Web Editor NEW
3.0 2.0 0.0 170 KB

A simple Result type to model an operation's ability to fail. Inspired by F#'s Result and "Railway Oriented Programming".

License: MIT License

C# 99.64% Dockerfile 0.36%
dotnet dotnetcore error-handling result railway-oriented-programming result-type exception-handling outcome async chain

ergo.result's Introduction

Result type with the ability to chain computations and first class Task/async support.

build codecov License: MIT nuget

✨ Features

  • A Result type that lets you wrap a return type Result<T>
  • Chainable validations/computations (handles the Defensive Programming)
  • First class async support - lets you chain validations on async methods
  • Inspired by functional languages but designed for Object Oriented Programming.
  • Falls back to a base Result class if you don't care about the contained response (much like Task<T> does)
  • Well tested

⚙️ Use

Return a Result class from a method that can fail:

using static Ergo.Result;

public Result<string> GetName(Dictionary<string, object> input)
{
    return input.HasKey("full_name")
        ? Success((string)input["full_name"])
        : Failure<string>("There was no 'full_name' key available in the dictionary");
}

public Result<string> GetFirstName(string fullName)
{
    var nameParts = fullName.Split(' ');

    return nameParts.Length > 1
        ? Success(nameParts.First())
        : Failure<string>("Ensure both a first and last name were submitted");
}

Once you have a Result, you can chain other methods that also return a Result class.

public Result<string> GetNameFromJson(string json)
{
    return SerializeDictionaryFromJson(json)
        .OnSuccess((jsonDictionary) => GetName(jsonDictionary))
        .OnSuccess((fullName) => GetFirstName(fullName));
        .OnFailure((failures) => FormatFailureMessages(failures))
}

Async support

Ergo was designed to work well even in Async situations. For instance, continuing from our previous example, any method that returns a Task<Result<T>> can be chained and used just like any other method. The only thing that changes is that you would then call await on the resulting object.

using static Ergo.Result;

public async Task<Result<User>> GetUserFromSecretKey(string secretKey)
{
    var user = await _userRepository.GetBySecretKey(secretKey);
    
    if (user is null)
        return Failure<User>("User isn't allowed access");

    return Success(user);
}

Any method that returns a Result from an async method can be chained like any other method that returns a Result. The consuming code would look something like this:

public async Task<Result<User>> GetAuthorizedUser()
{
    var asyncResult = GetAuthorizationHeader(Context)
        .OnSuccess(GetSecretKeyFromAuthorizationHeader)
        .OnSuccess(GetUserFromSecretKey) // this is the only method that is async - it returns a Task<Result<User>>
        .OnSuccess(ValidateUserIsActive);
        
    var result = await asyncResult; // we can await the response just like a Task!!!
    
    if (result.IsSuccessful)
        Console.WriteLine("It was successful");
    
    return result;
}

The ability to have the same methods available when a method returns a Task is achieved by converting the Task<Result> to a class AsyncResult behind the scenes. AsyncResult is designed to be fully compatible with a normal Result class and has the exact same methods and usage. Once you have an AsyncResult class, you just await it to pull out the Result object.

If you start out with a Task<Result> or Task<Result<T>> and want to convert it to an AsyncResult, there are constructors designed to help with the conversion.

var taskResult = Task.FromResult(Result.Success(""));
var asyncResult = new AsyncResult(taskResult);
// Now you can use all of the methods that `Result` has like `OnSuccess`, etc.

ergo.result's People

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

ergo.result's Issues

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.