Resulteles 1.0.2

dotnet add package Resulteles --version 1.0.2                
NuGet\Install-Package Resulteles -Version 1.0.2                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Resulteles" Version="1.0.2" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Resulteles --version 1.0.2                
#r "nuget: Resulteles, 1.0.2"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Resulteles as a Cake Addin
#addin nuget:?package=Resulteles&version=1.0.2

// Install Resulteles as a Cake Tool
#tool nuget:?package=Resulteles&version=1.0.2                

CI Nuget alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image alternate text is missing from this package README image

alternate text is missing from this package README image alternate text is missing from this package README image https://editorconfig.org/

Resulteles

Resulteles is a practical and lightweight library that define and facilitate the use of a success|failure data structure called Result (aka Either).

Getting started

NuGet package available:

$ dotnet add package Resulteles

Creating Results

You can create any result using the static methods on Result

// explicitly
var resultSuccess = Result.Ok<int, string>(42);
var resultError = Result.Error<int, string>("Something wrong!");

var processResult = Result.Try(() => { return 1; });
var processAsyncResult = Result.TryAsync(async () => { return await Task.FromResult(2); });

In most of the scenarios you will be using result as a return of a method or function, because of that it implements implicit convert operators from the generic types, reducing the generic type definition noise

public Result<int, string> GetEvenNumber(int number)
{
    if (number % 2 is 0)
        return number;
    else
        return $"{number} is not even!";
}

Reading Result Value

The Result type acts like a blackbox, by default there is no way to just get the typed value mostly because it can be two things, an Ok or an Error.

Result<int, string> result = GetEvenNumber(2);

// return -1 on error
int value1 = result.Match(
    n => n,
    error => -1
);

result.Switch(
    n => Console.WriteLine($"the number {n} is even"),
    error => Console.WriteLine(error)
);

// return 0 on error
var value2 = result.DefaultValue(0);

// lazily define the bad case value
var value3 = result.DefaultWith(e => e.Length);

// get the value or throw an exeption
var value4 = result.GetValueOrThrow();

// try/out pattern
if (result.TryGet(out var ok, out var error))
    Console.WriteLine($"the number {ok} is even");
else
    Console.WriteLine(error);

Operators

Most types you not even need to extract the value, you can just apply functions or combine with other Result types:

var result1 = Result.Ok<int, string>(1);

// Map the result value only when it is Ok
var result2 = result1.Select(n => n + 1);

// map for ok or error case
Result<string, int> result3 = result1.Select(n => n.ToString(), err => err.Length);

// SelectMany / Bind / FlatMamap
// Nested results transformation
Result<int, string> resultCombined = result1.SelectMany(n => GetEvenNumber(n));

// Zip Results together into a tuple
// only resolves as Ok when both are Ok
Result<(int, int), string> resultZip = result1.Zip(result2);

// Zip Results together
// only resolves as Ok when both are Ok
Result<int, string> resultSum = result1.Zip(result2, (a, b) => a + b);

// Enumerate result, empty when error, singleton when error (see ToArray() also)
IEnumerable<int> resultEnumerable = result1.AsEnumerable();

// LINQ QUERY
// you can use linq query to easily express map and bind

// simple map
var result2Linq = from r in result1 select r + 1;

// combining multiple results (fail fast at first non ok value)
var resultEvenSum =
    from a in GetEvenNumber(2)
    from b in GetEvenNumber(4)
    from c in GetEvenNumber(6)
    select a + b + c;
}

Async/Await

This library implements some helpers to seamless deal with async Result code

var result = GetEvenNumber(2);

// async match overload
int value1 = await result.Match(
    async n =>
    {
        await Task.Delay(n);
        return n;
    },
    _ => -1
);

await result.SwitchAsync(
    async n => await Console.Out.WriteLineAsync($"the number {n} is even"),
    async error => await Console.Error.WriteLineAsync(error)
);

// async projection counterparts
Result<int, string> resultWithDelay = await result.SelectAsync(async n =>
{
    await Task.Delay(n);
    return n;
});

// Transform Result<Task<int>, string> in a awaitable Task<Result<int, string>>
Result<int, string> resultWithDelay2 = await result.Select(async n =>
{
    await Task.Delay(n);
    return n;
}).ToTask();

Helper extensions

// result collection
var results = new[] { GetEvenNumber(2), GetEvenNumber(3), GetEvenNumber(4) };

// filter ok values
IEnumerable<int> okResultsOnly = results.GetOkValues(); // [2,4]

// map/reduce based on a result function
var numbers = new[] { 1, 2, 3, 4 };
var calculatedResults = numbers.ChooseResult(x => GetEvenNumber(x)); // [2,4]

// group a collection of result into a Result of collection
// collapse to error if any error is in the collection
Result<IReadOnlyList<int>, string> singleResult = results.GroupResults();

// Transform Result<Task<int>, string> in a awaitable Task<Result<int, string>>
Result<int, string> resultWithDelay2 = await results[0].Select(async n =>
{
    await Task.Delay(n);
    return n;
}).ToTask();

FluentAssertions Extensions

NuGet package available:

$ dotnet add package Resulteles.FluentAssertions

Alternatives

Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net6.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Resulteles:

Package Downloads
Resulteles.FluentAssertions

FluentAssertions extensions for Resulteles

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.0.2 503 7/7/2023
1.0.1 199 7/6/2023
1.0.0 154 7/6/2023