REslava.Result.SourceGenerators 1.15.0

Prefix Reserved
Suggested Alternatives

REslava.Result.AspNetCore

There is a newer version of this package available.
See the version list below for details.
dotnet add package REslava.Result.SourceGenerators --version 1.15.0
                    
NuGet\Install-Package REslava.Result.SourceGenerators -Version 1.15.0
                    
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="REslava.Result.SourceGenerators" Version="1.15.0">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="REslava.Result.SourceGenerators" Version="1.15.0" />
                    
Directory.Packages.props
<PackageReference Include="REslava.Result.SourceGenerators">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
                    
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 REslava.Result.SourceGenerators --version 1.15.0
                    
#r "nuget: REslava.Result.SourceGenerators, 1.15.0"
                    
#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 REslava.Result.SourceGenerators@1.15.0
                    
#: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=REslava.Result.SourceGenerators&version=1.15.0
                    
Install as a Cake Addin
#tool nuget:?package=REslava.Result.SourceGenerators&version=1.15.0
                    
Install as a Cake Tool

REslava.Result - Railway-Oriented Programming for .NET

<div align="center">

.NET C# NuGet Version License GitHub contributors GitHub Stars NuGet Downloads Test Coverage Test Suite

๐Ÿ“ Complete Functional Programming Framework + ASP.NET Integration + OneOf Extensions

</div>

Why REslava.Result?

The only .NET library that combines functional error handling with compile-time ASP.NET API generation.

REslava.Result FluentResults ErrorOr LanguageExt
Result<T> pattern โœ… โœ… โœ… โœ…
OneOf discriminated unions โœ… (2-4 types) โ€” โ€” โœ…
Maybe<T> โœ… โ€” โ€” โœ…
ASP.NET source generators โœ… โ€” โ€” โ€”
SmartEndpoints (zero-boilerplate APIs) โœ… โ€” โ€” โ€”
OpenAPI metadata auto-generation โœ… โ€” โ€” โ€”
Authorization & Policy support โœ… โ€” โ€” โ€”
Roslyn safety analyzers โœ… โ€” โ€” โ€”
Validation framework โœ… Basic โ€” โœ…
Zero dependencies โœ… โœ… โœ… โ€”

Unique advantage: SmartEndpoints auto-generates complete Minimal API endpoints from your business logic โ€” including routing, DI, HTTP status mapping, error handling, full OpenAPI metadata (.Produces<T>(), .WithSummary(), .WithTags()), and authorization (.RequireAuthorization(), .AllowAnonymous()). No other .NET library does this.


๐Ÿ“š Table of Contents

๐ŸŽฏ Section ๐Ÿ“– Description
๐Ÿš€ Quick Start Installation and complete generator showcase
๐Ÿ“š Choose Your Path Find exactly what you need
๐ŸŽฏ The Transformation: 70-90% Less Code See how boilerplate disappears
๐Ÿ“ REslava.Result Core Library Functional programming foundation
๐Ÿš€ ASP.NET Integration ResultToIResult and HTTP mapping
๐Ÿง  Advanced Patterns Maybe, LINQ, functional composition
๐Ÿ“ Complete Architecture How generators work internally
๐Ÿ“ฆ Package Structure What you get with each package
๐ŸŽฏ Quick Examples Real-world code samples
๐Ÿ“ˆ Production Benefits Enterprise-ready advantages
๐Ÿงช Testing & Quality Assurance 2,004+ tests passing
๐Ÿข Real-World Impact Success stories and use cases
๐Ÿ† Why Choose REslava.Result? Unique advantages
๐Ÿ“š Deep Dive Documentation Comprehensive guides
๐Ÿงช Quick Start Scenarios Hands-on tutorials
๐ŸŽฏ Roadmap Future development plans
๐Ÿค Contributing How to contribute
๐Ÿ“„ License MIT License details
๐Ÿ™ Acknowledgments Community credits
๐Ÿ“ˆ Version History Release notes and changes

๐Ÿš€ Quick Start

Installation

dotnet add package REslava.Result                      # Core library
dotnet add package REslava.Result.SourceGenerators     # ASP.NET source generators
dotnet add package REslava.Result.Analyzers            # Roslyn safety analyzers

Complete Generator Showcase

โšก SmartEndpoints - Zero-Boilerplate Fast APIs

Generate complete Minimal APIs from controllers with automatic HTTP mapping!

[AutoGenerateEndpoints(RoutePrefix = "/api/users")]
public class UserController {
    private readonly UserService _service;
    public UserController(UserService service) => _service = service;

    // ๐Ÿš€ DI + async โ†’ Automatic REST API with dependency injection!
    public async Task<OneOf<ValidationError, NotFoundError, User>>
        GetUser(int id) => await _service.GetUserByIdAsync(id);

    public async Task<OneOf<ValidationError, ConflictError, User>>
        CreateUser(CreateUserRequest request) => await _service.CreateAsync(request);

    public async Task<Result<List<User>>> GetUsers()
        => await _service.GetAllAsync();
}

๐ŸŽ‰ Generated Minimal API (Zero Manual Code!)

  • โœ… POST /api/users โ†’ 201/400/404/409 (OneOf4 auto-mapping!)
  • โœ… GET /api/users/{id} โ†’ 200/404 (OneOf2 auto-mapping!)
  • โœ… Full OpenAPI metadata โ€” .Produces<T>(200), .Produces(404), .WithSummary(), .WithTags() auto-generated from return types
  • โœ… Error handling automatically configured
  • โœ… HTTP status mapping automatically applied
  • โœ… Route grouping via MapGroup with automatic tag generation

๐Ÿ”ฅ Development Speed: 10x Faster

  • No manual route setup - automatic from method names
  • No manual error handling - automatic from return types
  • No manual status codes - automatic from error types
  • No manual API docs - OpenAPI + Scalar UI automatically generated
  • Self-explanatory code - business logic only
๐Ÿ”„ OneOf Extensions - Intelligent HTTP Mapping

Automatic error detection and HTTP status mapping for OneOf types:

// Error Types โ†’ HTTP Status Codes
ValidationError โ†’ 400 Bad Request
UserNotFoundError โ†’ 404 Not Found  
ConflictError โ†’ 409 Conflict
UnauthorizedError โ†’ 401 Unauthorized
ForbiddenError โ†’ 403 Forbidden
ServerError โ†’ 500 Internal Server Error

Supported Patterns:

  • OneOf2ToIResult<T1,T2> - Two-type error handling
  • OneOf3ToIResult<T1,T2,T3> - Three-type error handling
  • ๐Ÿ†• OneOf4ToIResult<T1,T2,T3,T4> - Four-type error handling (NEW v1.12.0!)
  • SmartEndpoints Integration - Uses extensions automatically in generated APIs
๐Ÿš€ Enhanced SmartEndpoints + OpenAPI Metadata (NEW!)

Feature: Full OpenAPI metadata auto-generated at compile time from return types Benefits: Scalar/Swagger UI shows typed responses, status codes, summaries, and tags โ€” zero manual configuration Use Case: Production-ready APIs with complete documentation from day one

๐Ÿ”ฅ What Makes SmartEndpoints Revolutionary:

// โœ… YOU WRITE: Pure business logic (5 lines)
[AutoGenerateEndpoints(RoutePrefix = "/api/orders")]
public class SmartOrderController {
    public async Task<OneOf<UserNotFoundError, InsufficientStockError, ValidationError, OrderResponse>>
        CreateOrder(CreateOrderRequest request) => await _service.CreateOrderAsync(request);
}

// ๐ŸŽ‰ GENERATOR PRODUCES: Complete endpoint with full OpenAPI metadata
var smartOrderGroup = endpoints.MapGroup("/api/orders")
    .WithTags("Smart Order");

smartOrderGroup.MapPost("/", async (CreateOrderRequest request, SmartOrderController service) =>
{
    var result = await service.CreateOrder(request);
    return result.ToIResult();
})
    .WithName("SmartOrder_CreateOrder")
    .WithSummary("Create order")
    .Produces<OrderResponse>(200)
    .Produces(400)   // โ† ValidationError
    .Produces(404)   // โ† UserNotFoundError
    .Produces(409);  // โ† InsufficientStockError

๐ŸŽฏ Everything Auto-Generated from Return Types:

  • Method name โ†’ HTTP method + .WithName() (CreateOrder โ†’ POST + SmartOrder_CreateOrder)
  • Class name โ†’ .WithTags() + MapGroup() (SmartOrderController โ†’ "Smart Order")
  • PascalCase โ†’ .WithSummary() (CreateOrder โ†’ "Create order")
  • Success type โ†’ .Produces<T>(200) (OrderResponse โ†’ typed 200 response)
  • Error types โ†’ .Produces(statusCode) (UserNotFoundError โ†’ 404, InsufficientStockError โ†’ 409)
  • Parameters โ†’ Route/body binding (int id โ†’ /{id}, request โ†’ JSON body)

โšก Zero Boilerplate Benefits:

  • No manual route configuration - inferred from class/method names
  • No manual error handling - automatic from OneOf types
  • No manual status codes - automatic from error type names
  • No manual OpenAPI metadata - .Produces(), .WithSummary(), .WithTags() all auto-generated
  • No manual endpoint names - globally unique names from controller + method
  • No manual ProblemDetails - automatic RFC 7807 compliance
๐ŸŽฏ ResultToIResult Extensions

Convert Result<T> types to proper HTTP responses:

public Result<User> GetUser(int id) { /* ... */ }
return GetUser(id).ToIResult(); // Automatic HTTP mapping


app.MapGet("/users/{id}", async (int id, IUserService service) =>
{
    return await service.GetUserAsync(id); // Auto-converts to HTTP response!
});

// ๐Ÿ†• v1.10.0: OneOf extensions also work!
app.MapGet("/users/oneof/{id}", async (int id) =>
{
    return GetOneOfUser(id); // Auto-converts OneOf<T1,T2,T3> too!
});
๐Ÿ›ก๏ธ Safety Analyzers โ€” Compile-Time Diagnostics

Catch common Result<T> and OneOf mistakes at compile time with 4 diagnostics and 2 code fixes:

// RESL1001 โ€” Unsafe .Value access without guard [Warning + Code Fix]
var result = GetUser(id);
var name = result.Value;        // โš ๏ธ Warning: Access to '.Value' without checking 'IsSuccess'
                                // ๐Ÿ’ก Fix A: Wrap in if (result.IsSuccess) { ... }
                                // ๐Ÿ’ก Fix B: Replace with result.Match(v => v, e => default)

// โœ… Safe alternatives:
if (result.IsSuccess)
    var name = result.Value;    // No warning โ€” guarded by IsSuccess

var name = result.Match(        // No warning โ€” pattern matching
    onSuccess: u => u.Name,
    onFailure: _ => "Unknown");
// RESL1002 โ€” Discarded Result<T> return value [Warning]
Save();                         // โš ๏ธ Warning: Return value of type 'Result<T>' is discarded
await SaveAsync();              // โš ๏ธ Warning: errors silently swallowed

// โœ… Safe alternatives:
var result = Save();            // No warning โ€” assigned
return Save();                  // No warning โ€” returned
// RESL1003 โ€” Prefer Match() over if-check [Info suggestion]
if (result.IsSuccess)           // โ„น๏ธ Suggestion: Consider using Match() instead
{
    var x = result.Value;
}
else
{
    var e = result.Errors;
}

// โœ… Cleaner with Match():
var x = result.Match(v => v, e => HandleErrors(e));
// RESL2001 โ€” Unsafe OneOf.AsT* access without IsT* check [Warning + Code Fix]
var oneOf = GetResult();        // OneOf<User, NotFound, ValidationError>
var user = oneOf.AsT1;          // โš ๏ธ Warning: Access to '.AsT1' without checking '.IsT1'
                                // ๐Ÿ’ก Fix: Replace with oneOf.Match(t1 => t1, t2 => throw ..., t3 => throw ...)

// โœ… Safe alternatives:
if (oneOf.IsT1)
    var user = oneOf.AsT1;      // No warning โ€” guarded

var user = oneOf.Match(         // No warning โ€” exhaustive
    user => user,
    notFound => throw ...,
    error => throw ...);
dotnet add package REslava.Result.Analyzers

๐Ÿ“š Choose Your Path

Find exactly what you need based on your goals:

๐ŸŽฏ I'm building a... ๐Ÿ“– Start Here ๐Ÿš€ What You'll Learn
Web API ๐ŸŒ ASP.NET Integration Auto-conversion, error mapping, OneOf extensions
Library/Service ๐Ÿ“ Core Library Result pattern, validation, functional programming
Custom Generator ๐Ÿ“– Custom Generator Guide Build your own source generators
Advanced App ๐Ÿง  Advanced Patterns Maybe, OneOf, validation rules
Testing ๐Ÿงช Testing & Quality 2,004+ tests, CI/CD, test strategies
Curious About Magic ๐Ÿ“ Complete Architecture How generators work, SOLID design

๐ŸŽฏ The Transformation: 70-90% Less Code

See how REslava.Result eliminates boilerplate in real .NET 10 applications:

โŒ BEFORE: Traditional Minimal API

// Manual error handling, validation, and HTTP responses
app.MapPost("/users", async (CreateUserRequest request, IUserService service) =>
{
    // Manual validation
    if (string.IsNullOrWhiteSpace(request.Email))
        return Results.BadRequest(new { error = "Email required" });
    
    if (!IsValidEmail(request.Email))
        return Results.BadRequest(new { error = "Invalid email" });
        
    // Manual duplicate checking
    if (await EmailExistsAsync(request.Email))
        return Results.Conflict(new { error = "Email already exists" });
        
    try
    {
        var user = await service.CreateUserAsync(request);
        return Results.Created($"/users/{user.Id}", user);
    }
    catch (ValidationException ex)
    {
        return Results.BadRequest(new { errors = ex.Errors });
    }
    catch (Exception ex)
    {
        return Results.Problem("Internal server error");
    }
});

โœ… AFTER: REslava.Result Magic

// Clean, declarative, type-safe - 3 lines instead of 25+
app.MapPost("/users", async (CreateUserRequest request) => 
    await CreateUser(request));

// Service layer handles everything elegantly
public async Task<Result<User>> CreateUser(CreateUserRequest request) =>
    await Result<CreateUserRequest>.Ok(request)
        .Ensure(r => !string.IsNullOrWhiteSpace(r.Email), "Email required")
        .Ensure(r => IsValidEmail(r.Email), "Invalid email format")
        .EnsureAsync(async r => !await EmailExistsAsync(r.Email), "Email already exists")
        .BindAsync(async r => await _userService.CreateUserAsync(r))
        .WithSuccess("User created successfully");

๐Ÿš€ Result: 70-90% less code, 100% type-safe, automatic HTTP responses, rich error context!


๐Ÿ“ REslava.Result Core Library

๐Ÿง  Functional Programming Foundation

Railway-Oriented Programming (ROP)

  • Immutable Results: Thread-safe functional data structures
  • Error Composition: Chain operations without exception handling
  • Success/Failure Pipelines: Clean separation of happy and error paths
  • Type Safety: Compile-time guarantees for error handling

๐Ÿ”ง Complete Method Catalog

Core Operations
// Factory Methods
Result<T>.Ok(value)                    // Success result
Result<T>.Fail("error")                 // Failure result
Result.Fail("error")                    // Non-generic failure

// Pattern Matching
result.Match(
    onSuccess: value => DoSomething(value),
    onFailure: errors => HandleErrors(errors)
);

// Value Access
result.Value                            // Throws if failed
result.GetValueOrDefault(defaultValue)  // Safe access
Functional Composition
// Bind (Chain operations)
var result = Result<int>.Ok(5)
    .Bind(x => Result<string>.Ok(x.ToString()))
    .Bind(s => ValidateEmail(s));

// Map (Transform success values)
var result = Result<int>.Ok(5)
    .Map(x => x * 2)
    .Map(x => x.ToString());

// Tap (Side effects without changing result)
var result = Result<User>.Ok(user)
    .Tap(u => LogUserAccess(u))
    .Tap(u => SendNotification(u));

// Ensure (Validation)
var result = Result<string>.Ok(email)
    .Ensure(e => IsValidEmail(e), "Invalid email format")
    .EnsureAsync(async e => !await EmailExistsAsync(e), "Email already registered");
Async Operations
// All methods have async variants
var result = await Result<int>.Ok(id)
    .BindAsync(async i => await GetUserAsync(i))
    .MapAsync(async user => await ToDtoAsync(user))
    .TapAsync(async dto => await LogAccessAsync(dto))
    .EnsureAsync(async dto => await ValidateDtoAsync(dto), "Invalid DTO");

๐Ÿ“Š LINQ Integration

Functional Query Comprehensions

// LINQ-like syntax for Result operations
var result = from user in GetUser(id)
            from validation in ValidateUser(user)
            from saved in SaveUser(validation)
            from notification in SendNotification(saved)
            select saved;

// Complex queries
var results = from id in userIds
             from user in GetUserAsync(id)
             from updated in UpdateUserAsync(user)
             select updated;

// Equivalent to method chaining
var result = GetUser(id)
    .Bind(ValidateUser)
    .Bind(SaveUser)
    .Bind(SendNotification);

๐ŸŽฏ Advanced Patterns

Maybe<T> - Null-Safe Optionals
// Instead of null references
Maybe<User> user = GetUserFromCache(id);
var email = user
    .Select(u => u.Email)
    .Filter(email => email.Contains("@"))
    .ValueOrDefault("no-reply@example.com");

// Safe operations
var result = user
    .Map(u => u.Name)
    .Bind(name => ValidateName(name))
    .ToResult(() => new UserNotFoundError(id));
OneOf - Discriminated Unions
// Internal OneOf implementation
OneOf<ValidationError, User> result = ValidateAndCreateUser(request);
return result.Match(
    case1: error => BadRequest(error),
    case2: user => Ok(user)
);

// Three-type OneOf
OneOf<ValidationError, NotFoundError, User> GetUser(int id) { /* logic */ }

// Conversion to Result
var result = oneOf.ToResult(); // Convert OneOf to Result
Validation Rules Framework
// Built-in validation
var validator = Validator.Create<User>()
    .Rule(u => u.Email, email => email.Contains("@"))
    .Rule(u => u.Name, name => !string.IsNullOrWhiteSpace(name))
    .Rule(u => u.Age, age => age >= 18, "Must be 18 or older");

var result = validator.Validate(user);

๐Ÿ”ง CRTP Pattern & Method Chaining

Curiously Recurring Template Pattern

// Fluent method chaining with CRTP
var result = Result<User>.Ok(user)
    .Ensure(ValidateEmail)
    .Map(ToDto)
    .Tap(SendWelcomeEmail)
    .Bind(SaveToDatabase)
    .WithSuccess("User created successfully")
    .WithTag("UserId", user.Id);

๐Ÿ”„ Advanced Extensions

Functional Composition

// Function composition
var createUser = Compose(
    ValidateRequest,
    MapToUser,
    SaveUser,
    SendNotification
);

// Higher-order functions
var results = users
    .Where(u => u.IsActive)
    .Select(u => ProcessUser(u))
    .Sequence(); // Turns IEnumerable<Result<T>> into Result<IEnumerable<T>>

// Traverse operations
var results = userIds
    .Traverse(id => GetUserAsync(id)); // Async version of Sequence

๐Ÿš€ ASP.NET Integration

๐ŸŒ ResultToIResult Extensions

Complete HTTP Method Support

// GET requests
return GetUser(id).ToIResult(); // 200 OK or 404/400

// POST requests  
return CreateUser(request).ToPostResult(); // 201 Created or 400

// PUT requests
return UpdateUser(id, request).ToPutResult(); // 200 OK or 404

// DELETE requests
return DeleteUser(id).ToDeleteResult(); // 204 No Content or 404

// PATCH requests
return PatchUser(id, request).ToPatchResult(); // 200 OK or 404

๐Ÿง  Smart HTTP Mapping

Intelligent Status Code Detection

  • "not found" โ†’ 404 Not Found
  • "validation" โ†’ 400 Bad Request
  • "unauthorized" โ†’ 401 Unauthorized
  • "forbidden" โ†’ 403 Forbidden
  • "conflict" โ†’ 409 Conflict
  • Default โ†’ 500 Internal Server Error

๐Ÿ“ Problem Details Integration

RFC 7807 Compliance

[MapToProblemDetails(StatusCode = 404, Title = "User Not Found")]
public class UserNotFoundError : Error
{
    public int UserId { get; }
    public UserNotFoundError(int userId) : base($"User {userId} not found")
    {
        UserId = userId;
        this.WithTag("UserId", userId);
    }
}

// Automatically generates:
{
    "type": "https://httpstatuses.com/404",
    "title": "User Not Found",
    "status": 404,
    "userId": 123
}

๐Ÿง  Advanced Patterns

Take your functional programming skills to the next level with these powerful patterns:

๐ŸŽฒ Maybe<T> - Safe Null Handling

Eliminate null reference exceptions permanently:

// โŒ Traditional null checking
string email = user?.Email?.ToLower();
if (string.IsNullOrEmpty(email))
{
    email = "no-reply@example.com";
}

// โœ… Maybe<T> functional approach
Maybe<User> maybeUser = GetUserFromCache(id);
string email = maybeUser
    .Select(u => u.Email)
    .Filter(e => !string.IsNullOrWhiteSpace(e))
    .Map(e => e.ToLower())
    .ValueOrDefault("no-reply@example.com");

// Chaining operations safely
var result = maybeUser
    .Filter(u => u.IsActive)
    .Select(u => u.Profile)
    .Select(p => p.Settings)
    .Select(s => s.Theme)
    .ValueOrDefault("default-theme");

๐Ÿ”€ OneOf - Discriminated Unions

Express multiple possible outcomes with type safety:

// Internal OneOf implementation
OneOf<ValidationError, NotFoundError, User> result = ValidateAndCreateUser(request);

// Pattern matching with exhaustive checking
return result.Match(
    case1: validationError => BadRequest(new { errors = validationError.Errors }),
    case2: notFoundError => NotFound(new { message = notFoundError.Message }),
    case3: user => CreatedAtAction(nameof(GetUser), new { id = user.Id }, user)
);

// ๐Ÿ†• v1.12.0: OneOf4 for complex scenarios
OneOf<ValidationError, NotFoundError, ConflictError, User> complexResult = 
    ValidateCreateUserWithConflictCheck(request);

return complexResult.Match(
    case1: validationError => BadRequest(new { errors = validationError.Errors }),
    case2: notFoundError => NotFound(new { message = notFoundError.Message }),
    case3: conflictError => Conflict(new { error = conflictError.Message }),
    case4: user => CreatedAtAction(nameof(GetUser), new { id = user.Id }, user)
);

// Conversion to Result for chaining
var userResult = result.ToResult(); // Convert OneOf to Result

// REslava.Result internal OneOf support (v1.12.0)
using REslava.Result.AdvancedPatterns.OneOf;
OneOf<ValidationError, User> internalResult = ValidateUser(request);
return internalResult.ToIResult(); // Auto-converts to HTTP response!

โœ… Validation Framework

Declarative validation with rich error context:

// Built-in validation rules
var validator = Validator.Create<User>()
    .Rule(u => u.Email, email => email.Contains("@"), "Invalid email format")
    .Rule(u => u.Name, name => !string.IsNullOrWhiteSpace(name), "Name is required")
    .Rule(u => u.Age, age => age >= 18, "Must be 18 or older")
    .Rule(u => u.Email, async email => !await EmailExistsAsync(email), "Email already exists");

// Execute validation
var validationResult = await validator.ValidateAsync(user);

// Chain with Result operations
var result = validationResult
    .Bind(validUser => CreateUserAsync(validUser))
    .WithSuccess("User created successfully");

// Custom validation rules
public class UniqueEmailRule : IValidationRule<User>
{
    public ValidationResult Validate(User user)
    {
        return EmailExistsAsync(user.Email).GetAwaiter().GetResult()
            ? ValidationResult.Fail("Email already exists")
            : ValidationResult.Success();
    }
}

๐Ÿ”„ Functional Composition

Build complex operations from simple functions:

// Function composition
Func<CreateUserRequest, Result<User>> createUserPipeline = Compose(
    ValidateRequest,
    MapToUser,
    ValidateUser,
    SaveUser,
    SendWelcomeEmail
);

// Use the composed function
var result = createUserPipeline(request);

// Higher-order functions with Result
var results = users
    .Where(u => u.IsActive)
    .Select(u => ProcessUser(u))
    .Sequence(); // Turns IEnumerable<Result<T>> into Result<IEnumerable<T>>

// Async traverse operations
var results = await userIds
    .Traverse(id => GetUserAsync(id)); // Async version of Sequence

// Error aggregation
var aggregatedResult = results
    .Map(users => users.ToList())
    .Tap(users => LogInfo($"Processed {users.Count} users"));

๐Ÿท๏ธ Rich Error Context

Add structured metadata for debugging and monitoring:

// Error with tags and metadata
var error = new UserNotFoundError(userId)
    .WithTag("UserId", userId)
    .WithTag("RequestId", requestId)
    .WithTag("Timestamp", DateTime.UtcNow)
    .WithMetadata("Endpoint", "/api/users/{id}")
    .WithMetadata("HttpMethod", "GET");

// Result with rich context
var result = Result<User>.Fail(error);

// Extract context for logging
if (result.IsFailed)
{
    var error = result.Errors.First();
    var userId = error.GetTag<string>("UserId");
    var requestId = error.GetTag<string>("RequestId");
    
    logger.LogWarning("User {UserId} not found for request {RequestId}", userId, requestId);
}

๐Ÿš€ Performance Patterns

Optimize for high-performance scenarios:

// Value objects for reduced allocations
public readonly record struct UserEmail(string Value)
{
    public static Result<UserEmail> Create(string email) =>
        string.IsNullOrWhiteSpace(email)
            ? Result<UserEmail>.Fail("Email required")
            : email.Contains("@")
                ? Result<UserEmail>.Ok(new UserEmail(email))
                : Result<UserEmail>.Fail("Invalid email format");
}

// Array pooling for high-throughput scenarios
using System.Buffers;

var result = Result<string[]>.Ok(ArrayPool<string>.Shared.Rent(1000))
    .Ensure(arr => arr.Length >= 1000, "Array too small")
    .Tap(arr => ArrayPool<string>.Shared.Return(arr));

// Memory-efficient validation
public ref struct ValidationSpan(ReadOnlySpan<char> input)
{
    public bool IsValid => !input.IsEmpty && input.Contains('@');
    public Result<ReadOnlySpan<char>> AsResult() =>
        IsValid ? Result<ReadOnlySpan<char>>.Ok(input) 
                : Result<ReadOnlySpan<char>>.Fail("Invalid email");
}

๐Ÿ“ Complete Architecture

REslava.Result is a comprehensive ecosystem with two main components that work together seamlessly:

๐Ÿ“ฆ Base Library: REslava.Result

Core Functional Programming Foundation

src/
โ”œโ”€โ”€ Result.cs                      # ๐ŸŽฏ Core Result<T> implementation
โ”œโ”€โ”€ Result.NonGeneric.cs           # ๐Ÿ“„ Non-generic Result for void operations
โ”œโ”€โ”€ AdvancedPatterns/
โ”‚   โ”œโ”€โ”€ Maybe.cs                   # ๐ŸŽฒ Safe null handling
โ”‚   โ”œโ”€โ”€ OneOf.cs                   # ๐Ÿ”€ Discriminated unions (2, 3, 4+ types)
โ”‚   โ”œโ”€โ”€ OneOfResultExtensions.cs   # ๏ฟฝ OneOf โ†” Result conversions
โ”‚   โ””โ”€โ”€ Validation/
โ”‚       โ”œโ”€โ”€ Validator.cs           # โœ… Validation framework
โ”‚       โ”œโ”€โ”€ IValidationRule.cs     # ๐Ÿ“‹ Validation rule interface
โ”‚       โ””โ”€โ”€ ValidationResult.cs    # ๐Ÿ“Š Validation results
โ”œโ”€โ”€ Extensions/
โ”‚   โ”œโ”€โ”€ ResultExtensions.cs        # ๐Ÿ”— LINQ and async extensions
โ”‚   โ”œโ”€โ”€ ResultMapExtensions.cs     # ๐Ÿ—บ๏ธ Mapping and transformation
โ”‚   โ””โ”€โ”€ ResultFunctionalExtensions.cs # ๐Ÿง  Functional composition
โ””โ”€โ”€ Utilities/
    โ”œโ”€โ”€ Compose.cs                 # ๐Ÿ”„ Function composition utilities
    โ””โ”€โ”€ Error.cs                   # โŒ Error base classes

๐Ÿš€ Source Generators: REslava.Result.SourceGenerators

Zero-Boilerplate Code Generation

SourceGenerator/
โ”œโ”€โ”€ Core/                           # ๐Ÿ“ Generator Infrastructure
โ”‚   โ”œโ”€โ”€ CodeGeneration/            # ๐Ÿ“ CodeBuilder utilities
โ”‚   โ”œโ”€โ”€ Utilities/                 # ๐ŸŒ HttpStatusCodeMapper, AttributeParser
โ”‚   โ”œโ”€โ”€ Configuration/             # โš™๏ธ Configuration base classes
โ”‚   โ””โ”€โ”€ Interfaces/                # ๏ฟฝ SOLID interfaces
โ”œโ”€โ”€ Generators/                     # ๐Ÿ“ฆ Individual Generators
โ”‚   โ”œโ”€โ”€ ResultToIResult/          # ๐ŸŽฏ Result โ†’ HTTP response conversion
โ”‚   โ”‚   โ”œโ”€โ”€ Attributes/            # ๐Ÿท๏ธ Auto-generated attributes
โ”‚   โ”‚   โ”œโ”€โ”€ CodeGeneration/        # ๐Ÿ’ป Extension method generation
โ”‚   โ”‚   โ””โ”€โ”€ Orchestration/         # ๐ŸŽผ Pipeline coordination
โ”‚   โ”œโ”€โ”€ OneOfToIResult/            # ๐Ÿš€ OneOf<T1,...,TN> โ†’ HTTP (consolidated v1.14.1)
โ”‚   โ”‚   โ”œโ”€โ”€ OneOf2ToIResultGenerator.cs  # ๐ŸŽฏ Thin wrapper (arity=2)
โ”‚   โ”‚   โ”œโ”€โ”€ OneOf3ToIResultGenerator.cs  # ๐ŸŽฏ Thin wrapper (arity=3)
โ”‚   โ”‚   โ”œโ”€โ”€ OneOf4ToIResultGenerator.cs  # ๐ŸŽฏ Thin wrapper (arity=4)
โ”‚   โ”‚   โ”œโ”€โ”€ Attributes/            # ๐Ÿท๏ธ Shared attribute generators
โ”‚   โ”‚   โ”œโ”€โ”€ CodeGeneration/        # ๐Ÿ’ป Arity-parameterized extensions
โ”‚   โ”‚   โ””โ”€โ”€ Orchestration/         # ๐ŸŽผ Single shared orchestrator
โ”‚   โ””โ”€โ”€ SmartEndpoints/            # โšก Auto-generate Minimal APIs (v1.11.0+)
โ”‚       โ”œโ”€โ”€ Attributes/            # ๐Ÿท๏ธ AutoGenerateEndpoints attribute
โ”‚       โ”œโ”€โ”€ CodeGeneration/        # ๐Ÿ’ป SmartEndpointExtensionGenerator
โ”‚       โ”œโ”€โ”€ Models/                # ๐Ÿ“‹ EndpointMetadata
โ”‚       โ””โ”€โ”€ Orchestration/         # ๐ŸŽผ SmartEndpointsOrchestrator
โ””โ”€โ”€ Tests/                         # ๐Ÿงช Comprehensive Test Suite (1,976+ tests)
    โ”œโ”€โ”€ OneOfToIResult/           # โœ… 12/12 tests (unified, covers arity 2/3/4)
    โ”œโ”€โ”€ SmartEndpoints/           # โœ… 4/4 tests passing
    โ”œโ”€โ”€ ResultToIResult/          # โœ… 6/6 tests passing
    โ”œโ”€โ”€ CoreLibrary/              # ๐Ÿ“š Base library tests
    โ””โ”€โ”€ GeneratorTest/             # ๏ฟฝ Integration tests

๐Ÿ“ Visual Architecture: See Core Type Hierarchy and Source Generator Pipeline for detailed Mermaid diagrams.

๐ŸŽฏ SOLID Principles in Action

Principle Implementation Benefit
Single Responsibility Separate classes for attributes, code generation, orchestration Zero duplicate generation, clear concerns
Open/Closed Interface-based design (IAttributeGenerator, ICodeGenerator, IOrchestrator) Easy to add new generators without modifying existing code
Liskov Substitution All generators implement common interfaces Interchangeable components, consistent behavior
Interface Segregation Focused interfaces for specific responsibilities Minimal contracts, easier testing
Dependency Inversion Constructor injection with abstractions Testable, maintainable, loosely coupled

๐Ÿ”„ How Components Work Together

graph TB
    A[Your Code] --> B[REslava.Result Base Library]
    B --> C[Result T / Maybe T / OneOf T]
    C --> D[Source Generators]
    D --> E[Generated Extensions]
    E --> F[ASP.NET Core IResult]

    G[REslava.Result OneOf] --> H[OneOf2ToIResult Generator]
    G --> I[OneOf3ToIResult Generator]
    G --> J[OneOf4ToIResult Generator]
    H --> F
    I --> F
    J --> F

    K[SmartEndpoints Generator] --> L[MapSmartEndpoints]
    L --> F

๐Ÿš€ Smart Auto-Detection (v1.10.0)

Zero Configuration Required

  • Setup Detection: Automatically detects your REslava.Result OneOf setup
  • Conflict Prevention: Generators only run when appropriate types are found
  • Perfect Coexistence: OneOf generators work seamlessly together
  • Zero Compilation Errors: Clean developer experience guaranteed

๐Ÿ“ฆ Package Structure

Three NuGet packages for a complete development experience:

Package Purpose
REslava.Result Core library โ€” Result<T>, Maybe<T>, OneOf, LINQ, validation
REslava.Result.SourceGenerators ASP.NET source generators โ€” SmartEndpoints, ToIResult, OneOf extensions
REslava.Result.Analyzers Roslyn safety analyzers โ€” RESL1001, RESL1002, RESL1003, RESL2001 diagnostics + code fixes

๐Ÿš€ NuGet Package Contents

REslava.Result.SourceGenerators.1.10.0.nupkg/
โ”œโ”€โ”€ analyzers/dotnet/cs/
โ”‚   โ”œโ”€โ”€ REslava.Result.SourceGenerators.dll           # Main source generators
โ”‚   โ””โ”€โ”€ REslava.Result.SourceGenerators.Core.dll      # Generator infrastructure
โ”œโ”€โ”€ content/
โ”‚   โ””โ”€โ”€ MapToProblemDetailsAttribute.cs                # Runtime attribute
โ”œโ”€โ”€ build/
โ”‚   โ””โ”€โ”€ REslava.Result.SourceGenerators.props         # MSBuild integration
โ”œโ”€โ”€ lib/
โ”‚   โ””โ”€โ”€ netstandard2.0/
โ”‚       โ””โ”€โ”€ REslava.Result.SourceGenerators.dll        # Reference assembly
โ””โ”€โ”€ README.md                                          # Package documentation

๐ŸŽฏ Generated Output Structure

When your project builds:

YourProject/
โ”œโ”€โ”€ obj/
โ”‚   โ””โ”€โ”€ GeneratedFiles/
โ”‚       โ””โ”€โ”€ net10.0/
โ”‚           โ””โ”€โ”€ REslava.Result.SourceGenerators/
โ”‚               โ”œโ”€โ”€ REslava.Result.SourceGenerators.Generators.ResultToIResult.ResultToIResultRefactoredGenerator/
โ”‚               โ”‚   โ”œโ”€โ”€ GenerateResultExtensionsAttribute.g.cs    # Auto-generated attribute
โ”‚               โ”‚   โ”œโ”€โ”€ MapToProblemDetailsAttribute.g.cs         # Auto-generated attribute
โ”‚               โ”‚   โ””โ”€โ”€ ResultToIResultExtensions.g.cs            # HTTP extension methods
โ”‚               โ”œโ”€โ”€ REslava.Result.SourceGenerators.Generators.OneOf2ToIResult.OneOf2ToIResultGenerator/
โ”‚               โ”‚   โ”œโ”€โ”€ GenerateOneOf2ExtensionsAttribute.g.cs    # OneOf2 attribute
โ”‚               โ”‚   โ”œโ”€โ”€ MapToProblemDetailsAttribute.g.cs         # OneOf2 mapping attribute
โ”‚               โ”‚   โ””โ”€โ”€ OneOf2ToIResultExtensions.g.cs            # OneOf2 HTTP extensions
โ”‚               โ””โ”€โ”€ REslava.Result.SourceGenerators.Generators.OneOf3ToIResult.OneOf3ToIResultGenerator/
โ”‚                   โ”œโ”€โ”€ GenerateOneOf3ExtensionsAttribute.g.cs    # OneOf3 attribute
โ”‚                   โ”œโ”€โ”€ MapToProblemDetailsAttribute.g.cs         # OneOf3 mapping attribute
โ”‚                   โ””โ”€โ”€ OneOf3ToIResultExtensions.g.cs            # OneOf3 HTTP extensions
โ””โ”€โ”€ bin/
    โ””โ”€โ”€ Your compiled application with auto-generated extensions

๐Ÿ”„ Build Integration

Automatic MSBuild Integration:


<Import Project="..\packages\REslava.Result.SourceGenerators.1.10.0\build\REslava.Result.SourceGenerators.props" />

What happens during build:

  1. Analysis Phase: Generators scan your code for Result<T>, OneOf<T1,T2>, OneOf<T1,T2,T3> usage
  2. Generation Phase: Creates appropriate extension methods and attributes
  3. Compilation Phase: Generated code is compiled into your assembly
  4. Runtime Phase: Extensions available for automatic HTTP conversion

๐ŸŽฏ Quick Examples

๐Ÿ“ฆ Core Library - Type-Safe Error Handling

// Fluent, chainable operations
var result = await Result<string>.Ok(email)
    .Ensure(e => IsValidEmail(e), "Invalid email format")
    .EnsureAsync(async e => !await EmailExistsAsync(e), "Email already registered")
    .BindAsync(async e => await CreateUserAsync(e))
    .WithSuccess("User created successfully");

// Pattern matching
return result.Match(
    onSuccess: user => CreatedAtAction(nameof(GetUser), new { id = user.Id }, user),
    onFailure: errors => BadRequest(new { errors })
);

๐Ÿš€ Source Generator - Zero Boilerplate

// Your service returns Result<T>
public async Task<Result<User>> GetUserAsync(int id)
{
    return await Result<int>.Ok(id)
        .Ensure(i => i > 0, "Invalid user ID")
        .BindAsync(async i => await _repository.FindAsync(i))
        .Ensure(u => u != null, new NotFoundError("User", id));
}

// Your controller just returns the Result - auto-converted!
app.MapGet("/users/{id}", async (int id) =>
    await _userService.GetUserAsync(id));

// ๐Ÿ†• v1.10.0: OneOf extensions also work!
public OneOf<ValidationError, NotFoundError, User> GetOneOfUser(int id) { /* logic */ }

app.MapGet("/users/oneof/{id}", async (int id) =>
    GetOneOfUser(id)); // Auto-converts OneOf too!

// HTTP responses are automatically generated:
// 200 OK with User data
// 404 Not Found with ProblemDetails
// 400 Bad Request with validation errors

๐Ÿง  Advanced Patterns - Functional Programming

// Maybe<T> for safe null handling
Maybe<User> user = GetUserFromCache(id);
var email = user
    .Select(u => u.Email)
    .Filter(email => email.Contains("@"))
    .ValueOrDefault("no-reply@example.com");

// ๐Ÿ†• v1.10.0: Enhanced OneOf support
OneOf<ValidationError, NotFoundError, User> result = ValidateAndCreateUser(request);
return result.Match(
    case1: error => BadRequest(error),
    case2: user => Ok(user)
);

// ๐Ÿ†• v1.10.0: OneOf with auto-detection
public OneOf<ValidationError, NotFoundError, User> GetUser(int id) { /* logic */ }
return GetUser(id).ToIResult(); // ๐Ÿ†• Automatic HTTP mapping!

๐Ÿ“ˆ Production Benefits

๐ŸŽฏ Challenge ๐Ÿš€ REslava.Result Solution
Hidden exceptions Explicit error contracts in method signatures
Complex error handling Fluent, chainable operations
Hard to debug failures Rich error context with tags
Inconsistent error responses Automatic RFC 7807 compliance
Slow development 70-90% less boilerplate code
๐Ÿ†• OneOf integration pain Smart auto-detection, zero configuration
๐Ÿ†• Multiple library conflicts Perfect coexistence, no compilation errors

๐Ÿงช Testing & Quality Assurance

๐Ÿ“Š Comprehensive Test Suite

1,928+ Tests Passing ๐ŸŽ‰

  • Source Generator Tests: 17 tests for all generators
  • Core Library Tests: 1,902 tests for REslava.Result functionality (1,902 core + 26 generator = 1,928 total)
  • Integration Tests: 9 endpoint tests for complete ASP.NET integration
  • Performance Tests: Memory and speed benchmarks

๐Ÿ“ Source Generator Test Architecture

Complete Test Coverage for v1.12.0

tests/REslava.Result.SourceGenerators.Tests/
โ”œโ”€โ”€ OneOf2ToIResult/          # โœ… 5/5 tests passing
โ”œโ”€โ”€ OneOf3ToIResult/          # โœ… 4/4 tests passing  
โ”œโ”€โ”€ OneOf4ToIResult/          # โœ… 5/5 tests passing (NEW!)
โ”œโ”€โ”€ ResultToIResult/          # โœ… 6/6 tests passing
โ”œโ”€โ”€ SmartEndpoints/           # โœ… 4/4 tests passing
โ”œโ”€โ”€ CoreLibrary/              # Core utilities tests
โ”œโ”€โ”€ GeneratorTest/             # Console validation tests
โ””โ”€โ”€ Legacy/                    # Historical tests (disabled)

๐ŸŽฏ Generator Test Coverage

OneOf4ToIResult Generator (NEW v1.12.0)

  • โœ… Extension method generation for OneOf<T1,T2,T3,T4>
  • โœ… Intelligent HTTP status mapping
  • โœ… Error type detection and handling
  • โœ… Attribute generation
  • โœ… Type combinations (ValidationError, NotFoundError, ConflictError, ServerError)
  • โœ… Conditional generation (no false positives)
  • โœ… HTTP mapping validation (T1โ†’400, T2โ†’200)

OneOf3ToIResult Generator

  • โœ… Extension method generation (OneOf3Extensions)
  • โœ… Attribute generation
  • โœ… Type combinations (3-way scenarios)
  • โœ… Conditional generation
  • โœ… HTTP mapping validation (T1โ†’400, T2โ†’400, T3โ†’200)

ResultToIResult Generator

  • โœ… Extension method generation
  • โœ… Attribute generation
  • โœ… Syntax tree detection
  • โœ… Conditional generation (zero false positives)

๐Ÿš€ CI/CD Pipeline

Automated Testing

# .github/workflows/ci.yml
- Build Solution: dotnet build --configuration Release
- Run Tests: dotnet test --configuration Release --no-build
- Total Tests: 1,928+ passing
- Coverage: 95%+ code coverage

๐Ÿงช Test Categories

Source Generator Tests

  • Unit Tests: Individual generator behavior
  • Integration Tests: Generator compilation scenarios
  • Regression Tests: Prevent breaking changes
  • Performance Tests: Generation speed and memory

Core Library Tests

  • Functional Tests: Result pattern operations
  • Async Tests: Task-based operations
  • Validation Tests: Error handling scenarios
  • Extension Tests: Method chaining and composition

๐Ÿ“ Sample Projects & Integration Tests

Real-World Validation

  • OneOfTest.Api: Live API testing with OneOf2ToIResult & OneOf3ToIResult
  • Integration Tests: End-to-end HTTP mapping validation
  • Performance Benchmarks: Memory allocation and speed tests
  • Production Samples: Enterprise-grade implementations

๐Ÿ” Test Quality Metrics

High Standards

  • โœ… 1,928/1,928 tests passing (100% success rate)
  • โœ… 95%+ code coverage (comprehensive coverage)
  • โœ… Zero flaky tests (reliable CI/CD)
  • โœ… Fast execution (complete suite < 10 seconds)
  • โœ… Clean architecture (SOLID test organization)

๐Ÿƒโ€โ™‚๏ธ Running Tests Locally

Quick Test Commands

# Run all tests (2,004+ tests)
dotnet test --configuration Release

# Run only Source Generator tests (16 tests)
dotnet test tests/REslava.Result.SourceGenerators.Tests/

# Run specific generator tests
dotnet test --filter "OneOf2ToIResult"    # 5 tests
dotnet test --filter "OneOf3ToIResult"    # 4 tests  
dotnet test --filter "ResultToIResult"    # 6 tests

# Clean environment before testing
./scripts/clean-before-test.ps1

Test Output Example

Test summary: total: 1928, failed: 0, succeeded: 1928, skipped: 0, duration: 7.8s
Build succeeded in 8.3s

๏ฟฝ Real-World Impact

๐Ÿข For Enterprise Teams

Explicit failure tracking replaces hidden exception flows

  • Rich error context with tags for debugging and monitoring
  • Better observability with structured error information
  • Consistent error handling across all services and APIs
  • Audit trails with detailed error metadata for compliance

๐Ÿงช For Test-Driven Development

Predictable patterns make unit tests simple and reliable

  • No complex exception setups - just assert on Result values
  • Faster test writing with deterministic results
  • Clear test scenarios - success, failure, and edge cases are explicit
  • Better test coverage - error paths are first-class citizens

๐Ÿ‘ฅ For Team Collaboration

Clear contracts between services and components

  • Consistent patterns across the entire codebase
  • Improved onboarding for new team members
  • Self-documenting code with explicit error types
  • Reduced cognitive load - one way to handle errors everywhere

๐Ÿš€ For Performance & Scalability

Optimized for modern applications

  • Zero allocation failures - immutable design prevents memory leaks
  • Compile-time guarantees - no runtime reflection or magic
  • AOT & NativeAOT compatible - works with trimming and native compilation
  • Minimal overhead - lightweight Result objects with smart optimizations

๏ฟฝ๐Ÿ† Why Choose REslava.Result?

โœ… Zero Dependencies

  • No external packages - Reduces security vulnerabilities
  • Small footprint - Only ~50KB compiled
  • Fast compilation - No complex dependency chains

โœ… Production-Ready

  • 95%+ code coverage - Reliable in production
  • Comprehensive testing - Unit, integration, and performance tests
  • Memory efficient - Immutable design, predictable allocations

โœ… Developer Experience

  • Rich IntelliSense - Extensive XML documentation
  • Modern C# - Supports .NET 8, 9, and 10
  • AOT compatible - Works with NativeAOT and trimming
  • ๐Ÿ†• Smart Auto-Detection - Zero configuration for v1.10.0

๐Ÿ“š Deep Dive Documentation

๐ŸŽฏ Navigate by Goal

I'm building a... ๐Ÿ“– Start Here ๐ŸŽฏ What You'll Learn
Web API ๐ŸŒ ASP.NET Integration Auto-conversion, OneOf extensions, error mapping
Library/Service ๐Ÿ“ Core Library Result pattern, validation, error handling
Custom Generator ๐Ÿ“– Custom Generator Guide Build your own source generators
Advanced App ๐Ÿง  Advanced Patterns Maybe, OneOf, validation rules
Testing ๐Ÿงช Testing & Quality 2,004+ tests, CI/CD, test strategies
Curious About Magic ๐Ÿ“ Complete Architecture How generators work, SOLID design

๐Ÿ“š Complete Reference

๐ŸŽฏ Hands-On Samples

  • ๐Ÿš€ FastMinimalAPI Demo - Production-ready .NET 10 Minimal API showcase

    • SmartEndpoints vs Manual - Side-by-side comparison (~85% less code)
    • OpenAPI 3.0 + Scalar UI - Modern API documentation
    • REslava.Result patterns - Result<T> and OneOf<T1,T2,T3,T4> discriminated unions
    • Real-world scenarios - Users, Products, Orders with full CRUD operations
    • Zero exception-based control flow - Type-safe error handling
  • ๐Ÿ“š Console Samples - 13 progressive examples from basic to advanced

    • Level 1: Core Result<T> patterns, validation pipelines, error handling
    • Level 2: Async operations, LINQ syntax, custom errors
    • Level 3: Maybe<T>, OneOf patterns, Resultโ†”OneOf conversions
  • ๐Ÿ”„ ASP.NET Integration Samples - Compare pure .NET 10 vs REslava.Result with source generators

    • MinimalApi.Net10.Reference - Pure .NET 10 implementation (baseline)
    • MinimalApi.Net10.REslava.Result.v1.7.3 - REslava.Result + source generators (70-90% less code)

๐Ÿงช Quick Start Scenarios

Installation

# Core functional programming library
dotnet add package REslava.Result

# ASP.NET integration + OneOf extensions
dotnet add package REslava.Result.SourceGenerators

# Roslyn safety analyzers (compile-time diagnostics)
dotnet add package REslava.Result.Analyzers

Scenario 1: Functional Programming Foundation

using REslava.Result;
using static REslava.Result.Functions;

// Core Result pattern usage
public Result<User> GetUser(int id)
{
    if (id <= 0) 
        return Result<User>.Fail("Invalid user ID");
    
    var user = FindUser(id);
    return user ?? Result<User>.Fail($"User {id} not found");
}

// Functional composition
public Result<UserDto> GetUserDto(int id) =>
    GetUser(id)
        .Map(ToDto)
        .Tap(LogAccess)
        .Ensure(dto => dto.IsActive, "User is inactive");

// LINQ integration
public Result<UserDto> GetUserDtoLinq(int id) =>
    from user in GetUser(id)
    from validation in ValidateUser(user)
    from dto in ToDto(user)
    select dto;

Scenario 2: ASP.NET Integration

[ApiController]
public class UsersController : ControllerBase
{
    // Automatic HTTP mapping
    [HttpGet("{id}")]
    public IResult GetUser(int id) => 
        GetUser(id).ToIResult(); // 200 OK or 404/400
    
    // POST with created response
    [HttpPost]
    public IResult CreateUser([FromBody] CreateUserRequest request) =>
        CreateUser(request).ToPostResult(); // 201 Created or 400
}

Scenario 3: OneOf Extensions (NEW!)

using REslava.Result.AdvancedPatterns.OneOf;
using Generated.OneOfExtensions;

// REslava.Result internal OneOf with automatic mapping
public OneOf<ValidationError, NotFoundError, User> GetUser(int id)
{
    if (id <= 0) 
        return new ValidationError("Invalid ID");
    
    var user = FindUser(id);
    return user ?? new NotFoundError($"User {id} not found");
}

[HttpGet("{id}")]
public IResult GetUser(int id) => 
    GetUser(id).ToIResult(); // 400, 404, or 200

๐ŸŽฏ Roadmap

v1.15.0 (Current) โœ…

  • Repository cleanup: removed unused Node.js toolchain, stale samples, incomplete templates
  • Emoji standardization: ๐Ÿ“ for all architecture/design references across documentation
  • Documentation refresh and consolidated release notes

v1.14.x โœ…

  • REslava.Result.Analyzers โ€” 4 diagnostics + 2 code fixes
    • RESL1001: Warns on unsafe .Value access + 2 code fixes (if-guard, Match)
    • RESL1002: Warns when Result<T> return value is discarded
    • RESL1003: Suggests Match() over if-check with .Value/.Errors
    • RESL2001: Warns on unsafe OneOf.AsT* access + code fix (Match)
  • OneOf generator consolidation (15 files โ†’ 7)
  • Shared GuardDetectionHelper for reusable guard-detection
  • 46 analyzer tests, 2,004+ total tests

v1.13.0 โœ…

  • SmartEndpoints: Authorization & Policy Support โ€” RequiresAuth, Roles, Policies, [SmartAllowAnonymous]
  • LINQ query comprehension syntax for Result<T> โ€” Select, SelectMany, Where + async variants
  • SmartEndpoints: OpenAPI Metadata Auto-Generation

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guide for details.


๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


๐Ÿ™ Acknowledgments

  • Functional Programming Community - For the ROP methodology and patterns
  • OneOf library - Excellent discriminated union implementation
  • Roslyn team - Powerful source generator framework
  • .NET community - Valuable feedback and contributions

๐ŸŽ‰ Ready to Transform Your Error Handling?

๐Ÿ“– Start with Getting Started Guide


<div align="center">

โญ Star this REslava.Result repository if you find it useful!

Made with โค๏ธ by Rafa Eslava for developers community

Report Bug โ€ข Request Feature โ€ข Discussions </div>


Contributors

See the full list of contributors in CONTRIBUTORS.md.


๐Ÿ“ˆ Version History

  • v1.15.0 - Repository cleanup: removed Node.js toolchain, stale samples, templates; emoji standardization (๐Ÿ“ for architecture)
  • v1.14.2 - Analyzers Phase 2+3: RESL1003 (prefer Match), RESL2001 (unsafe OneOf.AsT*), code fixes for RESL1001 & RESL2001, shared GuardDetectionHelper
  • v1.14.1 - Internal refactor: consolidated OneOf2/3/4ToIResult generators into single arity-parameterized OneOfToIResult (15 files โ†’ 7)
  • v1.14.0 - NEW: REslava.Result.Analyzers package (RESL1001 unsafe .Value access, RESL1002 discarded Result), package icons for all NuGet packages
  • v1.13.0 - SmartEndpoints Authorization & Policy Support (RequireAuthorization, AllowAnonymous, Roles, Policies, Produces(401))
  • v1.12.2 - SmartEndpoints OpenAPI metadata auto-generation (Produces, WithSummary, WithTags, MapGroup)
  • v1.12.1 - SmartEndpoints DI + async support, FastMinimalAPI demo, Console samples
  • v1.12.0 - OneOf4ToIResult generator, enhanced SmartEndpoints, 1,928 tests passing
  • v1.11.0 - SmartEndpoints generator for zero-boilerplate API generation
  • v1.10.3 - OneOf2ToIResult & OneOf3ToIResult generators
  • v1.10.2 - Initial ResultToIResult generator
  • v1.10.1 - Core Result types and error handling
  • v1.10.0 - Framework foundation with ROP patterns
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  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.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.32.0 161 2/28/2026 1.32.0 is deprecated because it is no longer maintained.
1.31.0 120 2/27/2026 1.31.0 is deprecated because it is no longer maintained.
1.30.0 125 2/27/2026 1.30.0 is deprecated because it is no longer maintained.
1.29.0 120 2/25/2026 1.29.0 is deprecated because it is no longer maintained.
1.28.0 118 2/25/2026 1.28.0 is deprecated because it is no longer maintained.
1.27.0 113 2/25/2026 1.27.0 is deprecated because it is no longer maintained.
1.26.0 136 2/24/2026 1.26.0 is deprecated because it is no longer maintained.
1.25.0 130 2/23/2026 1.25.0 is deprecated because it is no longer maintained.
1.24.0 129 2/23/2026 1.24.0 is deprecated because it is no longer maintained.
1.23.0 126 2/23/2026 1.23.0 is deprecated because it is no longer maintained.
1.22.0 136 2/18/2026 1.22.0 is deprecated because it is no longer maintained.
1.21.0 126 2/17/2026 1.21.0 is deprecated because it is no longer maintained.
1.20.0 128 2/17/2026 1.20.0 is deprecated because it is no longer maintained.
1.19.0 124 2/16/2026 1.19.0 is deprecated because it is no longer maintained.
1.18.0 124 2/16/2026 1.18.0 is deprecated because it is no longer maintained.
1.17.0 131 2/16/2026 1.17.0 is deprecated because it is no longer maintained.
1.16.0 124 2/16/2026 1.16.0 is deprecated because it is no longer maintained.
1.15.0 130 2/16/2026 1.15.0 is deprecated because it is no longer maintained.
Loading failed