Vostra.Result 1.2.1

dotnet add package Vostra.Result --version 1.2.1
                    
NuGet\Install-Package Vostra.Result -Version 1.2.1
                    
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="Vostra.Result" Version="1.2.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Vostra.Result" Version="1.2.1" />
                    
Directory.Packages.props
<PackageReference Include="Vostra.Result" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Vostra.Result --version 1.2.1
                    
#r "nuget: Vostra.Result, 1.2.1"
                    
#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.
#:package Vostra.Result@1.2.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Vostra.Result&version=1.2.1
                    
Install as a Cake Addin
#tool nuget:?package=Vostra.Result&version=1.2.1
                    
Install as a Cake Tool

Vostra.Result

A lean, async-friendly, dependency-free Result<T> for .NET. Stop throwing exceptions for expected failures and stop juggling success-flags and out-params: errors become ordinary, typed values the compiler tracks for you. The happy path stays implicit, the failure path is typed, and there is no .Value that hands you garbage on failure.

A method that can fail just returns Result<T> — a bare value or a bare error both convert to it implicitly, with no Result.Ok / Result.Fail ceremony. A missing lookup bridges to a typed failure in one line:

public Result<Order> GetOrder(int id) =>
    _db.Find(id).MapNullTo(() => Result.NotFoundError($"Order {id} not found"));

Consume it safely — the value is reachable only inside a branch that runs because it succeeded, so you can't forget to check:

string label = result.Match(onOk: o => $"#{o.Id}", onErr: errs => errs[0].Message);
if (result.TryGetValue(out var order)) { /* use order */ }

Compose without ever unwrapping. Each step runs only on success, the first error short-circuits the rest, and async folds in with a single await — no .Result, no nested awaits:

Result<Receipt> receipt =
    await GetOrderAsync(id)
        .Ensure(o => o.IsPaid, "Not paid.")   // false -> ValidationError
        .Then(o => ChargeAsync(o))            // T -> Task<Result<U>>, short-circuits on error
        .Map(r => r.Receipt);

When an operation can succeed as one of several shapes (not just value-or-error), say so in the type and match every arm exhaustively — the compiler makes sure you handle each one:

public Result<Pdf, Html> Render(Doc doc) =>
    doc.PrefersPrint ? RenderPdf(doc) : RenderHtml(doc);   // each arm (or an Error) converts implicitly

string mime = Render(doc).Match(
    pdf  => "application/pdf",
    html => "text/html",
    errs => errs[0].Code);                                 // error branch always present

What you get:

  • readonly struct, zero happy-path allocation, zero runtime dependencies.
  • Built-in error kinds (ValidationError, NotFoundError, ConflictError, AlreadyExistsError, UnauthorizedError, ForbiddenError, Error) with stable Code + neutral ErrorType — new one directly or discover them from IntelliSense via the matching Result.NotFoundError(...) factories; extend by subclassing ErrorBase.
  • Map / Then / Tap / Ensure / MapError (plus targeted MapError<TError>), full async matrix, LINQ (from … select), and Combine.
  • Re-word or re-tag an error while keeping its concrete kind: ErrorBase.WithMessage / WithCode / Prefix / WithMetadata / WithCausedBy.
  • Recovery: Else (try an alternative), ElseReturn (fall back to a value), Ignore (drop a failure kind on a valueless Result) — plus Result.Try (capture an exception as a failure), MapNullTo (nullable → Result), and HasError(type/code/<TError>).
  • Multi-success unions Result<T1,T2> / Result<T1,T2,T3> — one of several typed success shapes, or an error — consumed via exhaustive Match/Switch.
  • Companion packages: Vostra.Result.AspNetCore (Result → HTTP), Vostra.Result.Testing (transport-neutral chain & assert over any Task<Result<T>>), and Vostra.Result.AspNetCore.Testing (HTTP → Result test client).

Full walkthrough: see the Usage Guide.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  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.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages (2)

Showing the top 2 NuGet packages that depend on Vostra.Result:

Package Downloads
Vostra.Result.Testing

Transport-neutral testing toolkit for Vostra.Result — fluent chain-and-assert helpers over any Task<Result<T>> with rich diagnostics. Depends only on the core type.

Vostra.Result.AspNetCore

ASP.NET Core HTTP mapping for Vostra.Result — Result<T> to IResult with RFC 7807 ProblemDetails.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.1 321 7/5/2026
1.2.0 167 7/4/2026
1.1.3 208 6/26/2026
1.1.2 195 6/26/2026
1.1.1 182 6/26/2026