OrionResult 0.9.0
dotnet add package OrionResult --version 0.9.0
NuGet\Install-Package OrionResult -Version 0.9.0
<PackageReference Include="OrionResult" Version="0.9.0" />
<PackageVersion Include="OrionResult" Version="0.9.0" />
<PackageReference Include="OrionResult" />
paket add OrionResult --version 0.9.0
#r "nuget: OrionResult, 0.9.0"
#:package OrionResult@0.9.0
#addin nuget:?package=OrionResult&version=0.9.0
#tool nuget:?package=OrionResult&version=0.9.0
<p align="center"> <img src="docs/logo.png" alt="OrionResult" width="150" /> </p>
OrionResult
One error-model vocabulary for the Orion family. Most "failures" in real code are expected — validation rejected the input, the resource wasn't found, the caller isn't authorized — and modelling those as exceptions gives you invisible control flow, stack-trace tax, and forty different catch shapes at the HTTP boundary. So teams reach for a Result type, and now there are five of them, none agreeing on how a failure becomes a response.
OrionResult gives the family one Result/Option/Error vocabulary: a zero-alloc Result<T> struct, a structured Error (stable code + kind, not free-text), and the family's IOrionResult contract — so failures flow as data, not as control flow.
Features
Result<T>— areadonly struct, so the success path allocates nothing. Success carries the value; failure carries one or moreErrors. Railway composition withMap,Bind,Match,Ensure,Tap,OrElse.- Structured
Error— a machine-readableCode, a humanMessage, anErrorKindcategory, and optional field-level errors and extensions. Factory helpers (Error.NotFound,Error.Validation, …). Bridges to the spine'sOrionError. Option<T>— "maybe absent", distinct from "failed with a reason".Map/Bind/Match/OrElse,ToResult,FirstOrNone.- Implicit conversions keep call sites clean:
return value;is a success,return Error.NotFound(...);is a failure. - Implements
IOrionResult<T>— cross-cutting code (and, in a later wave, the RFC 9457ProblemDetailsbridge) reads any Orion result the same way. - AOT- and trim-clean, verified by a native-binary smoke test in CI; no reflection in the core. Multi-targets
net8.0,net9.0,net10.0.
Install
dotnet add package OrionResult
Quick start
using Moongazing.OrionResult;
Result<User> FindUser(UserId id) =>
repo.TryGet(id) is { } user
? user // implicit T -> success
: Error.NotFound("user.not_found", $"No user {id}"); // implicit Error -> failure
// Railway composition: each step runs only if the previous succeeded.
Result<ReceiptDto> Pay(UserId id, decimal amount) =>
FindUser(id)
.Ensure(u => u.IsActive, Error.Conflict("user.inactive", "User is deactivated"))
.Bind(u => ChargeCard(u, amount))
.Map(charge => new ReceiptDto(charge));
// Collapse to a value by handling both cases.
string message = Pay(id, 10m).Match(
receipt => $"charged {receipt.Total}",
errors => $"failed: {errors[0].Code}");
Option<T> for "maybe absent":
Option<Email> primary = user.Emails.FirstOrNone(e => e.IsPrimary);
Email best = primary.OrElse(Email.Empty);
// Turn absence into a typed failure when you need a Result.
Result<Email> required = primary.ToResult(Error.Validation("email.required", "A primary email is required"));
Catch a boundary exception once and convert it — a deliberate, local escape hatch:
Result<Config> parsed = Result.Try(
() => Config.Parse(raw),
ex => Error.Validation("config.invalid", ex.Message));
Versioning
Follows Semantic Versioning. Multi-targets net8.0, net9.0, and net10.0. Binds to Orion.Abstractions 1.x. The RFC 9457 ProblemDetails / ToHttpResult HTTP mapping and async combinators arrive in later waves; this release is the core value types.
Documentation
- CHANGELOG.md — release notes.
Contributing
Contributions are welcome. See CONTRIBUTING.md and the CODE_OF_CONDUCT.md.
License
MIT.
| Product | Versions 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 is compatible. 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. |
-
net10.0
- Orion.Abstractions (>= 1.0.0)
-
net8.0
- Orion.Abstractions (>= 1.0.0)
-
net9.0
- Orion.Abstractions (>= 1.0.0)
NuGet packages (2)
Showing the top 2 NuGet packages that depend on OrionResult:
| Package | Downloads |
|---|---|
|
OrionEnvelope
One HTTP contract for the whole API: every success is a typed { data, meta }, every failure is an RFC 9457 problem+json, and pagination metadata rides in the same envelope — projected mechanically from OrionResult's Result<T> instead of hand-serialized per endpoint. Source-gen JSON, reflection-free and AOT-clean. Wave 1 is the types and the projection; the ASP.NET filters and OpenAPI schema land in later waves. |
|
|
OrionCache
Cache-aside with per-key single-flight, OrionClock-driven expiration, case-sensitive tag invalidation, Option-returning reads, and OpenTelemetry. AOT-clean in-memory core; Redis L2 is planned. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.9.0 | 252 | 7/27/2026 |